diff --git a/README.md b/README.md index da3fda0..ad1d034 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,11 @@ Package in Go for parsing Google Protocol Buffers [.proto files version 2 + 3] (https://developers.google.com/protocol-buffers/docs/reference/proto3-spec) -This repository also includes 3 commands. The `protofmt` tool is for formatting .proto files. The `proto2xsd` tool is for generating XSD files from .proto version 3 files. The `proto2gql` tool is for generating the GraphQL Schema. +### install -### usage as package + go get -u -v github.com/emicklei/proto + +### usage package main @@ -23,56 +25,15 @@ This repository also includes 3 commands. The `protofmt` tool is for formatting defer reader.Close() parser := proto.NewParser(reader) definition, _ := parser.Parse() - formatter := proto.NewFormatter(os.Stdout, " ") - formatter.Format(definition) + log.Println(definition) } -### usage of proto2xsd command - - > proto2xsd -help - Usage of proto2xsd [flags] [path ...] - -ns string - namespace of the target types (default "http://your.company.com/domain/version") - -w write result to an XSD files instead of stdout - -See folder `cmd/proto2xsd/README.md` for more details. - -### usage of proto2gql command - - > proto2gql -help - Usage of proto2gql [flags] [path ...] - - -std_out - Writes transformed files to stdout - -txt_out string - Writes transformed files to .graphql file - -go_out string - Writes transformed files to .go file - -js_out string - Writes transformed files to .js file - -package_alias value - Renames packages using given aliases - -resolve_import value - Resolves given external packages - -no_prefix - Disables package prefix for type names +### contributions -See folder `cmd/proto2gql/README.md` for more details. - -### usage of protofmt command - - > protofmt -help - Usage of protofmt [flags] [path ...] - -w write result to (source) files instead of stdout - -See folder `cmd/protofmt/README.md` for more details. - -### how to install - - go get -u -v github.com/emicklei/proto +See (https://github.com/emicklei/proto-contrib) for contributions on top of this package such as protofmt, proto2xsd and proto2gql. #### known issues -- the proto2 test file in protofmt folder contains character escape sequences that are currently not accepted by the scanner. See line 537 and 573. +- the proto2 test file in (https://github.com/emicklei/proto-contrib/cmd/protofmt) folder contains character escape sequences that are currently not accepted by the scanner. See line 537 and 573. © 2017, [ernestmicklei.com](http://ernestmicklei.com). MIT License. Contributions welcome. \ No newline at end of file diff --git a/aligned.go b/aligned.go deleted file mode 100644 index f9d51dc..0000000 --- a/aligned.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package proto - -import "strings" -import "bytes" - -type aligned struct { - source string - left bool - padding bool -} - -var ( - alignedEquals = leftAligned(" = ") - alignedShortEquals = leftAligned("=") - alignedSpace = leftAligned(" ") - alignedComma = leftAligned(", ") - alignedEmpty = leftAligned("") - alignedSemicolon = leftAligned(";") -) - -func leftAligned(src string) aligned { return aligned{src, true, true} } -func rightAligned(src string) aligned { return aligned{src, false, true} } -func notAligned(src string) aligned { return aligned{src, false, false} } - -func (a aligned) preferredWidth() int { - if !a.hasAlignment() { - return 0 // means do not force padding because of this source - } - return len(a.source) -} - -func (a aligned) formatted(indentSeparator string, indentLevel, width int) string { - if !a.padding { - // if the source has newlines then make sure the correct indent level is applied - buf := new(bytes.Buffer) - for _, each := range a.source { - buf.WriteRune(each) - if '\n' == each { - buf.WriteString(strings.Repeat(indentSeparator, indentLevel)) - } - } - return buf.String() - } - if a.left { - return a.source + strings.Repeat(" ", width-len(a.source)) - } - return strings.Repeat(" ", width-len(a.source)) + a.source -} - -func (a aligned) hasAlignment() bool { return a.left || a.padding } diff --git a/cmd/proto2gql/Makefile b/cmd/proto2gql/Makefile deleted file mode 100644 index 6ed3dac..0000000 --- a/cmd/proto2gql/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -.PHONY: build install generate vet compile test doc fmt lint docker - -default: test compile - -compile: - go build -v -o ./proto2gql ./*.go - -test: - go test ./*.go diff --git a/cmd/proto2gql/README.md b/cmd/proto2gql/README.md deleted file mode 100644 index 6ad65a0..0000000 --- a/cmd/proto2gql/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# proto2gql - -GraphQL Schema conversion tool for Google Protocol Buffers version 3 - - > proto2gql -help - Usage of proto2gql [flags] [path ...] - - -std_out - Writes transformed files to stdout - -txt_out string - Writes transformed files to .graphql file - -go_out string - Writes transformed files to .go file - -js_out string - Writes transformed files to .js file - -package_alias value - Renames packages using given aliases - -resolve_import value - Resolves given external packages - -no_prefix - Disables package prefix for type names - -### build - make \ No newline at end of file diff --git a/cmd/proto2gql/converter.go b/cmd/proto2gql/converter.go deleted file mode 100644 index 701603b..0000000 --- a/cmd/proto2gql/converter.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import "strings" - -type Converter struct { - noPrefix bool - pkgAliases map[string]string -} - -func (c *Converter) NewTypeName(scope *Scope, name string) string { - return scope.packageName + strings.Join(scope.path, "") + name -} - -func (c *Converter) OriginalTypeName(scope *Scope, name string) string { - switch len(scope.path) { - case 0: - return name - case 1: - return scope.path[0] + "." + name - default: - return strings.Join(scope.path, ".") + "." + name - } -} - -func (c *Converter) PackageName(parts []string) string { - var name string - - if c.noPrefix == true { - return name - } - - if len(c.pkgAliases) > 0 { - alias, exists := c.pkgAliases[strings.Join(parts, ".")] - - if exists == true { - return alias - } - } - - for _, segment := range parts { - name += strings.Title(segment) - } - - return name -} diff --git a/cmd/proto2gql/file.go b/cmd/proto2gql/file.go deleted file mode 100644 index 0e413c0..0000000 --- a/cmd/proto2gql/file.go +++ /dev/null @@ -1,78 +0,0 @@ -package main - -import ( - "os" - "io/ioutil" - "path/filepath" -) - -type FileWriter struct { - filename string - file *os.File - closeTag string - isClosed bool -} - -func NewFileWriter(filename string, openTag, closeTag string) (*FileWriter, error) { - file, err := ioutil.TempFile(filepath.Dir(filename), "proto2gql") - - if err != nil { - return nil, err - } - - file.Write([]byte(openTag)) - - return &FileWriter{filename, file, closeTag, false}, nil -} - -func (fw *FileWriter) IsClosed() bool { - return fw.isClosed -} - -func (fw *FileWriter) Write(p []byte) (n int, err error) { - return fw.file.Write(p) -} - -func (fw *FileWriter) Save() error { - if fw.isClosed == true { - return nil // return an error? - } - - tmpName := fw.file.Name() - - fw.file.Write([]byte(fw.closeTag)) - - if err := fw.Close(); err != nil { - return err - } - - if err := os.MkdirAll(filepath.Dir(fw.filename), os.ModePerm); err != nil { - return err - } - - return os.Rename(tmpName, fw.filename) -} - -func (fw *FileWriter) Remove() error { - if fw.isClosed == true { - return nil // return an error? - } - - tmpName := fw.file.Name() - - if err := fw.Close(); err != nil { - return err - } - - return os.Remove(tmpName) -} - -func (fw *FileWriter) Close() error { - if fw.isClosed == false { - fw.isClosed = true - - return fw.file.Close() - } - - return nil -} \ No newline at end of file diff --git a/cmd/proto2gql/main.go b/cmd/proto2gql/main.go deleted file mode 100644 index e8c561b..0000000 --- a/cmd/proto2gql/main.go +++ /dev/null @@ -1,253 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io" - "os" - "path/filepath" - "strings" -) - -type ( - StringMap map[string]string -) - -func (s *StringMap) String() string { - pairs := make([]string, 0, len(*s)) - - for key, value := range *s { - pairs = append(pairs, key+"="+value) - } - - return strings.Join(pairs, ",") -} - -func (s *StringMap) Set(value string) error { - parts := strings.Split(value, ",") - - for _, part := range parts { - pair := strings.Split(part, "=") - - (*s)[strings.TrimSpace(pair[0])] = strings.TrimSpace(pair[1]) - } - - return nil -} - -var ( - stdOut bool - - txtOut string - - goOut string - - jsOut string - - resolveImports StringMap - - packageAliases StringMap - - noPrefix bool -) - -func main() { - resolveImports = make(StringMap) - packageAliases = make(StringMap) - - flag.BoolVar(&stdOut, "std_out", false, "Writes transformed files to stdout") - flag.StringVar(&txtOut, "txt_out", "", "Writes transformed files to .graphql file") - flag.StringVar(&goOut, "go_out", "", "Writes transformed files to .go file") - flag.StringVar(&jsOut, "js_out", "", "Writes transformed files to .js file") - flag.Var(&resolveImports, "resolve_import", "Resolves given external packages") - flag.Var(&packageAliases, "package_alias", "Renames packages using given aliases") - flag.BoolVar(&noPrefix, "no_prefix", false, "Disables package prefix for type names") - - flag.Parse() - - if len(flag.Args()) == 0 { - flag.Usage() - os.Exit(0) - } - - var transformer *Transformer - writers := make([]io.Writer, 0, 5) - - if stdOut == true { - writers = append(writers, os.Stdout) - } - - if txtOut != "" { - writer, err := createTextWriter(txtOut) - - if err != nil { - gracefullyTerminate(err, writers) - } - - writers = append(writers, writer) - } - - if goOut != "" { - writer, err := createGoWriter(goOut) - - if err != nil { - gracefullyTerminate(err, writers) - } - - writers = append(writers, writer) - } - - if jsOut != "" { - writer, err := createJsWriter(jsOut) - - if err != nil { - gracefullyTerminate(err, writers) - } - - writers = append(writers, writer) - } - - if len(writers) == 0 { - fmt.Println("output not defined") - os.Exit(0) - } - - transformer = NewTransformer( - io.MultiWriter(writers...), - withResolvingImports(resolveImports), - withPackageAliases(packageAliases), - withNoPrefix(noPrefix), - ) - - var err error - - for _, filename := range flag.Args() { - if err = readAndTransform(filename, transformer); err != nil { - fmt.Println(err.Error()) - break - } - } - - if saveErr := saveWriters(writers); saveErr != nil && err == nil { - err = saveErr - } - - if err != nil { - os.Exit(1) - } -} - -func withResolvingImports(imports StringMap) func(transformer *Transformer) { - return func(t *Transformer) { - for key, url := range imports { - t.Import(key, url) - } - } -} - -func withPackageAliases(aliases StringMap) func(transformer *Transformer) { - return func(t *Transformer) { - for pkg, alias := range aliases { - t.SetPackageAlias(pkg, alias) - } - } -} - -func withNoPrefix(noPrefix bool) func(transformer *Transformer) { - return func(t *Transformer) { - t.DisablePrefix(noPrefix) - } -} - -func ensureExtension(filename, expectedExt string) string { - ext := filepath.Ext(filename) - - if ext == "" { - return filename + expectedExt - } - - if ext != expectedExt { - return strings.Replace(filename, ext, expectedExt, -1) - } - - return filename -} - -func createTextWriter(filename string) (io.Writer, error) { - return NewFileWriter(ensureExtension(filename, ".graphql"), "", "") -} - -func createGoWriter(filename string) (io.Writer, error) { - filename = ensureExtension(filename, ".go") - abs, err := filepath.Abs(filename) - - if err != nil { - return nil, err - } - - name := strings.Replace(filepath.Base(abs), ".go", "", -1) - - openTag := "package " + filepath.Base(filepath.Dir(abs)) + "\n \n" - openTag += "var " + strings.Title(name) + " = `\n" - - return NewFileWriter(filename, openTag, "\n`") -} - -func createJsWriter(filename string) (io.Writer, error) { - openTag := "module.exports = `\n" - - return NewFileWriter(ensureExtension(filename, ".js"), openTag, "\n`") -} - -func saveWriters(writers []io.Writer) error { - var err error - - for _, writer := range writers { - fw, ok := writer.(*FileWriter) - - if ok == true { - if err == nil { - err = fw.Save() - - if err != nil { - fmt.Println(err.Error()) - } - } else { - fw.Remove() - } - } - } - - return err -} - -func gracefullyTerminate(err error, writers []io.Writer) { - for _, writer := range writers { - fw, ok := writer.(*FileWriter) - - if ok == true { - fw.Remove() - } - } - - fmt.Println("error occured: " + err.Error()) - os.Exit(1) -} - -func readAndTransform(filename string, transformer *Transformer) error { - // open for read - file, err := os.Open(filename) - - if err != nil { - return err - } - - defer file.Close() - - transformer.SetFilename(filename) - if err := transformer.Transform(file); err != nil { - return err - } - - return nil -} diff --git a/cmd/proto2gql/scope.go b/cmd/proto2gql/scope.go deleted file mode 100644 index fd85a96..0000000 --- a/cmd/proto2gql/scope.go +++ /dev/null @@ -1,153 +0,0 @@ -package main - -import ( - "path" - "strings" -) - -type ( - Type struct { - packageName string - name string - } - - Scope struct { - converter *Converter - packageName string - path []string - types map[string]*Type - imports map[string]*Type - children map[string]*Scope - } -) - -func NewScope(converter *Converter) *Scope { - return &Scope{ - converter: converter, - path: make([]string, 0, 5), - types: make(map[string]*Type), - imports: make(map[string]*Type), - children: make(map[string]*Scope), - } -} - -func (s *Scope) Fork(name string) *Scope { - p := make([]string, len(s.path)) - - copy(p, s.path) - - childScope := &Scope{ - converter: s.converter, - packageName: s.packageName, - types: s.types, // share types collection - path: append(p, name), - children: make(map[string]*Scope), - } - - s.children[name] = childScope - - return childScope -} - -func (s *Scope) SetPackageName(name string) { - s.packageName = s.converter.PackageName(strings.Split(name, ".")) -} - -func (s *Scope) AddLocalType(name string) { - typeName := s.converter.OriginalTypeName(s, name) - - _, ok := s.types[typeName] - - if ok == false { - s.types[typeName] = &Type{ - packageName: s.packageName, - name: s.converter.NewTypeName(s, name), - } - } -} - -func (s *Scope) AddImportedType(filename string) { - dir := path.Dir(filename) - name := strings.Replace(path.Base(filename), ".proto", "", -1) - ref := strings.Replace(dir, "/", ".", -1) - - var packageName string - - if dir == "." { - packageName = s.packageName - } else { - packageName = s.converter.PackageName(strings.Split(dir, "/")) - } - - s.imports[ref] = &Type{packageName, name} -} - -func (s *Scope) ResolveTypeName(ref string) string { - builtin, ok := BUILTINS[ref] - - if ok == true { - return builtin - } - - // try to find one in a global scope - scoped, ok := s.types[ref] - - if ok == true { - return scoped.name - } - - // try to find one among nested types - nested, ok := s.types[s.converter.OriginalTypeName(s, ref)] - - if ok == true { - return nested.name - } - - var foundInChildren string - - for _, childScope := range s.children { - res := childScope.ResolveTypeName(ref) - - if res != ref { - foundInChildren = res - break - } - } - - if foundInChildren != "" { - return foundInChildren - } - - // if we are still here, probably it's an imported type - - // if type does not contain "." it means it's from the same package - if strings.Contains(ref, ".") == false { - // from the same package - imported, ok := s.imports["."] - - if ok == true { - return imported.packageName + ref - } - } else { - // if it has "." it means it's from other package - parts := strings.Split(ref, ".") - - var tail string - - for idx, segment := range parts { - if tail == "" { - tail = segment - } else { - tail += "." + segment - } - - imported, ok := s.imports[tail] - - if ok == true { - return imported.packageName + strings.Join(parts[idx+1:], "") - } - } - } - - return ref -} diff --git a/cmd/proto2gql/transformer.go b/cmd/proto2gql/transformer.go deleted file mode 100644 index 6215d27..0000000 --- a/cmd/proto2gql/transformer.go +++ /dev/null @@ -1,135 +0,0 @@ -package main - -import ( - "io" - "net/http" - "strings" - - "github.com/emicklei/proto" -) - -type ( - ExternalPackage struct { - url string - resolved bool - } - - Transformer struct { - out io.Writer - filename string - imports map[string]*ExternalPackage - pkgAliases map[string]string - noPrefix bool - } -) - -func NewTransformer(out io.Writer, opts ...func(transformer *Transformer)) *Transformer { - res := &Transformer{ - out, - "", - make(map[string]*ExternalPackage), - make(map[string]string), - false, - } - - for _, opt := range opts { - opt(res) - } - - return res -} - -func (t *Transformer) DisablePrefix(value bool) { - t.noPrefix = value -} - -func (t *Transformer) Import(name string, url string) { - name = strings.TrimSpace(name) - - _, exists := t.imports[name] - - if exists == false { - t.imports[name] = &ExternalPackage{strings.TrimSpace(url), false} - } -} - -func (t *Transformer) SetPackageAlias(pkg, alias string) { - t.pkgAliases[pkg] = alias -} - -func (t *Transformer) SetFilename(filename string) { - t.filename = filename -} - -func (t *Transformer) Transform(input io.Reader) error { - parser := proto.NewParser(input) - parser.Filename(t.filename) - - def, err := parser.Parse() - - if err != nil { - return err - } - - visitor := NewVisitor(&Converter{ - noPrefix: t.noPrefix, - pkgAliases: t.pkgAliases, - }) - - toDownload := make(map[string]*ExternalPackage) - - for _, element := range def.Elements { - - switch element := element.(type) { - case *proto.Import: - // we collect imports to be resolved afterwards - pkg, needed := t.imports[element.Filename] - - if needed == true { - if pkg.resolved == false { - _, added := toDownload[pkg.url] - - if added == false { - toDownload[pkg.url] = pkg - } - } - } - } - - element.Accept(visitor) - - visitor.Flush(t.out) - } - - if len(toDownload) > 0 { - packages := make([]*ExternalPackage, 0, len(toDownload)) - - for _, pkg := range toDownload { - packages = append(packages, pkg) - } - - return t.resolveExternalPackages(packages) - } - - return nil -} - -func (t *Transformer) resolveExternalPackages(packages []*ExternalPackage) error { - for _, pkg := range packages { - resp, err := http.Get(pkg.url) - - if err != nil { - return err - } - - pkg.resolved = true - - err = t.Transform(resp.Body) - - if err != nil { - return err - } - } - - return nil -} diff --git a/cmd/proto2gql/transformer_test.go b/cmd/proto2gql/transformer_test.go deleted file mode 100644 index 63afcf3..0000000 --- a/cmd/proto2gql/transformer_test.go +++ /dev/null @@ -1,747 +0,0 @@ -package main - -import ( - "bytes" - "strings" - "testing" -) - -func TestTransformBasicMessage(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - message Simple { - double field_double = 1; - float field_float = 2; - int32 field_int32 = 3; - int64 field_int64 = 4; - uint64 field_uint64 = 5; - sint32 field_sint32 = 6; - sint64 field_sint64 = 7; - fixed32 field_fixed32 = 8; - fixed64 field_fixed64 = 9; - sfixed32 field_sfixed32 = 10; - sfixed64 field_sfixed64 = 11; - bool field_bool = 12; - string field_string = 13; - bytes field_bytes = 14; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestSimple { - field_double: Float - field_float: Float - field_int32: Int - field_int64: Int - field_uint64: Int - field_sint32: Int - field_sint64: Int - field_fixed32: Int - field_fixed64: Int - field_sfixed32: Int - field_sfixed64: Int - field_bool: Boolean - field_string: String - field_bytes: [String] -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformNestedMessages(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package api.myapp; - - message Outer { // Level 0 - int32 field_int32 = 1; - - message MiddleAA { // Level 1 - string field_string = 1; - - message Inner { // Level 2 - int64 ival = 1; - bool booly = 2; - } - } - - message MiddleBB { // Level 1 - int64 field_int64 = 1; - - message Inner { // Level 2 - int32 ival = 1; - bool booly = 2; - } - } - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type ApiMyappOuter { - field_int32: Int -} - -type ApiMyappOuterMiddleAA { - field_string: String -} - -type ApiMyappOuterMiddleAAInner { - ival: Int - booly: Boolean -} - -type ApiMyappOuterMiddleBB { - field_int64: Int -} - -type ApiMyappOuterMiddleBBInner { - ival: Int - booly: Boolean -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformUseOfNestedTypes(t *testing.T) { - schema := []byte(` -syntax = "proto3"; -package api.myapp; - -message SearchResponse { - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } - - repeated Result results = 1; -} - -message SomeOtherMessage { - SearchResponse.Result result = 1; -} - - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type ApiMyappSearchResponse { - results: [ApiMyappSearchResponseResult] -} - -type ApiMyappSearchResponseResult { - url: String - title: String - snippets: [String] -} - -type ApiMyappSomeOtherMessage { - result: ApiMyappSearchResponseResult -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformNestedMessagesHoisting(t *testing.T) { - schema := []byte(` -syntax = "proto3"; -package api.myapp; - -message SearchResponse { - repeated Result results = 1; - - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } -} - - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type ApiMyappSearchResponse { - results: [ApiMyappSearchResponseResult] -} - -type ApiMyappSearchResponseResult { - url: String - title: String - snippets: [String] -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformNestedTypes(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - message A { - int64 field_int64 = 1; - } - - message B { - A field_a = 1; - } - - message C { - repeated B field_b = 1; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestA { - field_int64: Int -} - -type TestB { - field_a: TestA -} - -type TestC { - field_b: [TestB] -} -` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformEnums(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - enum Corpus { - UNIVERSAL = 0; - WEB = 1; - IMAGES = 2; - LOCAL = 3; - NEWS = 4; - PRODUCTS = 5; - VIDEO = 6; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -enum TestCorpus { - UNIVERSAL - WEB - IMAGES - LOCAL - NEWS - PRODUCTS - VIDEO -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformNestedEnums(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - message Person { - string firstName = 1; - string lastName = 2; - - enum Gender { - UNKNOWN = 0; - MALE = 1; - FEMALE = 2; - } - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestPerson { - firstName: String - lastName: String -} - -enum TestPersonGender { - UNKNOWN - MALE - FEMALE -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformImportedTypes(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "google/protobuf/any.proto"; - - message ErrorStatus { - string message = 1; - repeated google.protobuf.Any details = 2; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestErrorStatus { - message: String - details: [GoogleProtobufAny] -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformImportedNestedTypes(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "google/protobuf/any.proto"; - - message OtherMessage { - google.protobuf.Any.Type details = 1; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestOtherMessage { - details: GoogleProtobufAnyType -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformImportedTypesFromSamePackage(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "any.proto"; - - message ErrorStatus { - string message = 1; - repeated Any details = 2; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestErrorStatus { - message: String - details: [TestAny] -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformResolveImportedTypes(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "google/protobuf/timestamp.proto"; - - message ErrorStatus { - google.protobuf.Timestamp time = 1; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - - transformer.Import("google/protobuf/timestamp.proto", "https://raw.githubusercontent.com/google/protobuf/master/src/google/protobuf/timestamp.proto") - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type TestErrorStatus { - time: GoogleProtobufTimestamp -} - -type GoogleProtobufTimestamp { - seconds: Int - nanos: Int -} - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformWithNoTypePrefix(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "google/protobuf/timestamp.proto"; - - message ErrorStatus { - google.protobuf.Timestamp time = 1; - } - - message SearchResponse { - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } - - repeated Result results = 1; - } - - message SomeOtherMessage { - SearchResponse.Result result = 1; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - transformer.DisablePrefix(true) - transformer.Import("google/protobuf/timestamp.proto", "https://raw.githubusercontent.com/google/protobuf/master/src/google/protobuf/timestamp.proto") - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type ErrorStatus { - time: Timestamp -} - -type SearchResponse { - results: [SearchResponseResult] -} - -type SearchResponseResult { - url: String - title: String - snippets: [String] -} - -type SomeOtherMessage { - result: SearchResponseResult -} - -type Timestamp { - seconds: Int - nanos: Int -} - - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformWithPackageAliases(t *testing.T) { - schema := []byte(` - syntax = "proto3"; - package test; - - import "google/protobuf/timestamp.proto"; - - message ErrorStatus { - google.protobuf.Timestamp time = 1; - } - - message SearchResponse { - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } - - repeated Result results = 1; - } - - message SomeOtherMessage { - SearchResponse.Result result = 1; - } - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - transformer.SetPackageAlias("test", "Dashboard") - transformer.SetPackageAlias("google.protobuf", "") - transformer.Import("google/protobuf/timestamp.proto", "https://raw.githubusercontent.com/google/protobuf/master/src/google/protobuf/timestamp.proto") - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -type DashboardErrorStatus { - time: Timestamp -} - -type DashboardSearchResponse { - results: [DashboardSearchResponseResult] -} - -type DashboardSearchResponseResult { - url: String - title: String - snippets: [String] -} - -type DashboardSomeOtherMessage { - result: DashboardSearchResponseResult -} - -type Timestamp { - seconds: Int - nanos: Int -} - - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} - -func TestTransformWithPackageAliases2(t *testing.T) { - schema := []byte(` -syntax = "proto3"; -package com.users.api; - -enum ContactType { - PHONE = 0; - EMAIL = 1; - WEBSITE = 2; - FACEBOOK = 3; - TWITTER = 4; - INSTAGRAM = 5; - YOUTUBE = 6; - FLICKR = 7; - MEDIUM = 8; -} - -message Contact { - uint64 id = 1; - ContactType type = 2; - string value = 3; -} - `) - - input := new(bytes.Buffer) - input.Write(schema) - - output := new(bytes.Buffer) - transformer := NewTransformer(output) - transformer.SetPackageAlias("com.users.api", "User") - - if err := transformer.Transform(input); err != nil { - t.Fatal(err) - } - - expected := ` -enum UserContactType { - PHONE - EMAIL - WEBSITE - FACEBOOK - TWITTER - INSTAGRAM - YOUTUBE - FLICKR - MEDIUM -} - -type UserContact { - id: Int - type: UserContactType - value: String -} - - ` - - expected = strings.TrimSpace(expected) - actual := strings.TrimSpace(output.String()) - - if expected != actual { - t.Fatalf("Expected %s to equal to %s", expected, actual) - } -} diff --git a/cmd/proto2gql/visitor.go b/cmd/proto2gql/visitor.go deleted file mode 100644 index 8545738..0000000 --- a/cmd/proto2gql/visitor.go +++ /dev/null @@ -1,151 +0,0 @@ -package main - -import ( - "bytes" - "github.com/emicklei/proto" - "io" -) - -var BUILTINS = map[string]string{ - "double": "Float", - "float": "Float", - "int32": "Int", - "int64": "Int", - "uint32": "Int", - "uint64": "Int", - "sint32": "Int", - "sint64": "Int", - "fixed32": "Int", - "fixed64": "Int", - "sfixed32": "Int", - "sfixed64": "Int", - "bool": "Boolean", - "string": "String", - "bytes": "[String]", -} - -type ( - Visitor struct { - scope *Scope - buff *bytes.Buffer - children []*Visitor - } -) - -func NewVisitor(converter *Converter) *Visitor { - return &Visitor{ - buff: new(bytes.Buffer), - children: make([]*Visitor, 0, 5), - scope: NewScope(converter), - } -} - -func (v *Visitor) Fork(name string) *Visitor { - child := &Visitor{ - buff: new(bytes.Buffer), - children: make([]*Visitor, 0, 5), - scope: v.scope.Fork(name), - } - - v.children = append(v.children, child) - - return child -} - -func (v *Visitor) Flush(out io.Writer) { - out.Write(v.buff.Bytes()) - - v.buff.Reset() - - for _, child := range v.children { - child.Flush(out) - } -} - -func (v *Visitor) VisitMessage(m *proto.Message) { - v.buff.WriteString("\n") - - v.scope.AddLocalType(m.Name) - - v.buff.WriteString("type " + v.scope.converter.NewTypeName(v.scope, m.Name) + " {\n") - - fields := make([]*proto.NormalField, 0, len(m.Elements)) - - for _, element := range m.Elements { - - field, ok := element.(*proto.NormalField) - - // it's not a nested message/enum - if ok == true { - // we put it in array in order to process nested messages first - // in case they exist and have them in a scope - fields = append(fields, field) - } else { - // if so, create a nested visitor - // we need to track a parent's name - // in order to generate a unique name for nested ones - // we create another visitor in order to unfold nested types since GraphQL does not support nested types - element.Accept(v.Fork(m.Name)) - } - } - - // now, having all nested messages in a scope, we can transform fields - for _, field := range fields { - field.Accept(v) - } - - v.buff.WriteString("}\n") - -} -func (v *Visitor) VisitService(s *proto.Service) {} -func (v *Visitor) VisitSyntax(s *proto.Syntax) {} -func (v *Visitor) VisitPackage(p *proto.Package) { - v.scope.SetPackageName(p.Name) -} -func (v *Visitor) VisitOption(o *proto.Option) {} -func (v *Visitor) VisitImport(i *proto.Import) { - v.scope.AddImportedType(i.Filename) -} -func (v *Visitor) VisitNormalField(field *proto.NormalField) { - v.buff.WriteString(" " + field.Name + ":") - - typeName := v.scope.ResolveTypeName(field.Type) - - if field.Repeated == false { - v.buff.WriteString(" " + typeName) - } else { - v.buff.WriteString(" [" + typeName + "]") - } - - if field.Required == true { - v.buff.WriteString("!") - } - - v.buff.WriteString("\n") -} -func (v *Visitor) VisitEnumField(i *proto.EnumField) { - v.buff.WriteString(" " + i.Name + "\n") -} -func (v *Visitor) VisitEnum(e *proto.Enum) { - v.scope.AddLocalType(e.Name) - - v.buff.WriteString("\n") - - v.buff.WriteString("enum " + v.scope.converter.NewTypeName(v.scope, e.Name) + " {\n") - - for _, element := range e.Elements { - element.Accept(v) - } - - v.buff.WriteString("}\n") -} -func (v *Visitor) VisitComment(e *proto.Comment) {} -func (v *Visitor) VisitOneof(o *proto.Oneof) {} -func (v *Visitor) VisitOneofField(o *proto.OneOfField) {} -func (v *Visitor) VisitReserved(r *proto.Reserved) {} -func (v *Visitor) VisitRPC(r *proto.RPC) {} -func (v *Visitor) VisitMapField(f *proto.MapField) {} - -// proto2 -func (v *Visitor) VisitGroup(g *proto.Group) {} -func (v *Visitor) VisitExtensions(e *proto.Extensions) {} diff --git a/cmd/proto2xsd/Dockerfile b/cmd/proto2xsd/Dockerfile deleted file mode 100644 index 42d85b8..0000000 --- a/cmd/proto2xsd/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM alpine:3.6 - -COPY proto2xsd / - -ENTRYPOINT ["./proto2xsd"] \ No newline at end of file diff --git a/cmd/proto2xsd/README.md b/cmd/proto2xsd/README.md deleted file mode 100644 index 6295872..0000000 --- a/cmd/proto2xsd/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# proto2xsd - -XSD conversion tool for Google ProtocolBuffers version 3 - - > proto2xsd -help - Usage of proto2xsd [flags] [path ...] - -ns string - namespace of the target types (default "http://your.company.com/domain/version") - -w write result to XSD files instead of stdout - -## Docker -A Docker image is available on [DockerhuB](https://hub.docker.com/r/emicklei/proto2xsd/). -It can be used as part of your continuous integration build pipeline. - -### build - GOOS=linux go build - docker build -t emicklei/proto2xsd:latest -t emicklei/proto2xsd:0.2 . - -### run - docker run -v $(pwd):/data emicklei/proto2xsd -ns http://company/your/v1 /data/YOUR.proto - -© 2017, [ernestmicklei.com](http://ernestmicklei.com). MIT License. \ No newline at end of file diff --git a/cmd/proto2xsd/main.go b/cmd/proto2xsd/main.go deleted file mode 100644 index 9ec52bd..0000000 --- a/cmd/proto2xsd/main.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package main - -import ( - "fmt" - "io" - "os" - - "flag" - - "bytes" - "io/ioutil" - - "encoding/xml" - - "github.com/emicklei/proto" -) - -var ( - oOverwrite = flag.Bool("w", false, "write result to (source) file instead of stdout") - oNamespace = flag.String("ns", "http://your.company.com/domain/version", "namespace of the target types") -) - -func main() { - flag.Parse() - if len(flag.Args()) == 0 { - flag.Usage() - os.Exit(0) - } - exitCode := 0 - for _, each := range flag.Args() { - if err := readConvertWrite(each); err != nil { - println(err.Error()) - exitCode = 1 - } - } - os.Exit(exitCode) -} - -func readConvertWrite(filename string) error { - // open for read - file, err := os.Open(filename) - if err != nil { - return err - } - // buffer before write - buf := new(bytes.Buffer) - if err := convert(filename, file, buf); err != nil { - return err - } - if *oOverwrite { - // write back to input - if err := ioutil.WriteFile(filename, buf.Bytes(), os.ModePerm); err != nil { - return err - } - } else { - // write to stdout - if _, err := io.Copy(os.Stdout, bytes.NewReader(buf.Bytes())); err != nil { - return err - } - } - return nil -} - -func convert(filename string, input io.Reader, output io.Writer) error { - parser := proto.NewParser(input) - parser.Filename(filename) - def, err := parser.Parse() - if err != nil { - return err - } - types, err := buildXSDTypes(def) - if err != nil { - return err - } - fmt.Fprintln(output, xml.Header) - elements, err := buildXSDElements(def) - if err != nil { - return err - } - schema := buildXSDSchema(*oNamespace) - schema.Types = types - schema.Elements = elements - data, err := xml.MarshalIndent(schema, "", "\t") - if err != nil { - return err - } - output.Write(data) - - return nil -} diff --git a/cmd/proto2xsd/xsd.go b/cmd/proto2xsd/xsd.go deleted file mode 100644 index 53431bd..0000000 --- a/cmd/proto2xsd/xsd.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package main - -import ( - "encoding/xml" - "strings" - "unicode" - "unicode/utf8" - - "github.com/emicklei/proto" -) - -// XSDSchema represents a schema -type XSDSchema struct { - XMLName xml.Name `xml:"schema"` - StandardNamespace string `xml:"xmlns,attr"` - TargetNamespace string `xml:"targetNamespace,attr"` - TargetAlias string `xml:"xmlns:target,attr"` - Version string `xml:"xmlns:version,attr"` - ElementFormDefault string `xml:"elementFormDefault,attr"` - Types []XSDComplexType - Elements []XSDElement -} - -func buildXSDSchema(target string) XSDSchema { - return XSDSchema{ - StandardNamespace: "http://www.w3.org/2001/XMLSchema", - TargetNamespace: target, - TargetAlias: target, - Version: "v1", - ElementFormDefault: "qualified", - } -} - -// XSDComplexType represents a complexType -type XSDComplexType struct { - XMLName xml.Name `xml:"complexType"` - Name string `xml:"name,attr"` - Comment string `xml:",comment"` - Sequence XSDSequence `xml:"sequence"` -} - -// XSDSequence represents a sequence as part of e.g. complexType -type XSDSequence struct { - Elements []XSDElement `xml:"element"` -} - -// XSDElement represents an element as part of e.g. sequence -type XSDElement struct { - XMLName xml.Name `xml:"element"` - Name string `xml:"name,attr"` - Comment string `xml:",comment"` - Type string `xml:"type,attr"` - MinOccurs string `xml:"minOccurs,attr,omitempty"` - MaxOccurs string `xml:"maxOccurs,attr,omitempty"` -} - -func buildXSDTypes(def *proto.Proto) (list []XSDComplexType, err error) { - for _, each := range def.Elements { - if msg, ok := each.(*proto.Message); ok { - list = append(list, buildComplexType(msg)) - } - } - return list, nil -} - -func buildXSDElements(def *proto.Proto)(list []XSDElement, err error) { - for _, each := range def.Elements { - if msg, ok := each.(*proto.Message); ok { - list = append(list, buildElementType(msg)) - } - } - return list, nil -} - -func buildElementType(msg *proto.Message) XSDElement { - et := XSDElement{} - et.Name = msg.Name + "Element" - et.Type = "target:" + msg.Name - return et -} - -func buildComplexType(msg *proto.Message) XSDComplexType { - ct := XSDComplexType{} - ct.Name = msg.Name - if msg.Comment != nil { - ct.Comment = msg.Comment.Message() - } - sq := XSDSequence{} - for _, other := range msg.Elements { - // TODO other field types - if field, ok := other.(*proto.NormalField); ok { - sq = withNormalFieldToSequence(field, sq) - } - } - ct.Sequence = sq - return ct -} - -func withNormalFieldToSequence(f *proto.NormalField, s XSDSequence) XSDSequence { - el := XSDElement{} - el.Name = f.Name - if f.Comment != nil { - el.Comment = strings.Join(f.Comment.Lines, "\n") - } - el.Type = mapProtoSimpleTypeToXSDSimpleType(f.Type) - // proto 3 fields are always optional. TODO check proto version - el.MinOccurs = "0" - if f.Repeated { - el.MaxOccurs = "unbounded" - } - s.Elements = append(s.Elements, el) - return s -} - -func mapProtoSimpleTypeToXSDSimpleType(pt string) string { - switch pt { - case "fixed32", "uint32", "int32", "sfixed32", "sint32": - return "integer" - case "uint64", "int64", "fixed64", "sfixed64", "sint64": - return "long" - case "bool": - return "boolean" - default: - // assume that target types are in uppercase - r, _ := utf8.DecodeRuneInString(pt) - if unicode.IsUpper(r) { - return "target:" + pt - } - return pt - } -} diff --git a/cmd/protofmt/Dockerfile b/cmd/protofmt/Dockerfile deleted file mode 100644 index 89ea6b4..0000000 --- a/cmd/protofmt/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM alpine:3.6 - -COPY protofmt / - -ENTRYPOINT ["./protofmt"] \ No newline at end of file diff --git a/cmd/protofmt/README.md b/cmd/protofmt/README.md deleted file mode 100644 index 162ee40..0000000 --- a/cmd/protofmt/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# protofmt - -formatting tool for Google ProtocolBuffers version 2 and 3 - - > protofmt -help - Usage of protofmt [flags] [path ...] - -w write result to (source) file instead of stdout - -### format style - -#### indentation -***protofmt*** uses 2 spaces for indentation. -The Formatter type can be initialized with a different indentSeparator string. - -#### comments -Parsing and formatting support two styles of comments. -Inline comments are written with 2 leading forward slashed ( // ). -If an inline comment is present after a statement then it is written with a leading space. -Multi-line comments are written with a header ( /\*[newline] ) and a footer ( [space]\*/[newline] ) on separate lines. - - /* - Multi line - comment - */ - message X { - - } - -#### empty line separators -Different structural top level definitions (message,service,enum) are separated with an empty line. - - message Y {} - message Z {} - - enum E {} -Comments are preceeded with an empty line unless it is defined after a statement. - - // nice message to send - message Greeting { - // what is said - string content = 1; // first - } - -#### structural elements in top level definitions -Fields in messages and enums, rpc-s in services are all formatted in a columnar style with aligments. - - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - -This example shows that field types are right aligned. -Field names are left aligned. -Field sequence numbers are right aligned. - -#### options -Embedded options (specified for fields) have a compact format without special alignment. - - message Defaults { - optional bool default_bool = 1 [default = true ]; - optional string default_string = 2 [default = "hello"]; - } - -Top level options have right aligned names and values. - - option optimize_for = SPEED; - option java_outer_classname = "UnittestProto"; - - -#### RPCs in services -Request and Response types of rpc elements are left aligned. -Closing brackets are right aligned. - - service SearchService { - // comment - rpc Search (SearchRequest) returns ( SearchResponse); // Search - rpc Find (Finder ) returns (stream Result ); // Find - } - -## Docker -A Docker image is available on Dockerhub. -It can be used as part of your continuous integration build pipeline. - -### build - GOOS=linux go build - docker build -t emicklei/protofmt . - -### run - docker run -v $(pwd):/data emicklei/protofmt /data/YOUR.proto - -© 2017, [ernestmicklei.com](http://ernestmicklei.com). MIT License. \ No newline at end of file diff --git a/cmd/protofmt/comments.proto b/cmd/protofmt/comments.proto deleted file mode 100644 index 757d4e0..0000000 --- a/cmd/protofmt/comments.proto +++ /dev/null @@ -1,59 +0,0 @@ -/* - begin -*/ - -// comment 1 -// comment 2 -syntax = "proto"; // inline 1 - -// comment 3 -// comment 4 -package test; // inline 2 - -// comment 5 -// comment 6 -message Test { - // comment 7 - // comment 8 - int64 i = 1; // inline 3 - /* - cstyle - */ -} - -// comment 9 -enum Codes { - // comment 10 - Unknown = 0; // inline 4 -} - -// comment 11 -service API { - // comment 12 - rpc doit (In) returns (Out); // inline 5 -} - -// comment 13 -import "some.proto"; // inline 6 - -// comment 14 -option (test.option) = 42; // inline 7 - -message MyMessage { - oneof type { - // comment 15 - Null null = 1; - } -} - -// comment 16 -message super { - // comment 17 - message sub { - // comment 18 - message subbest { - // comment 19 - Wrapped string = 1; - } - } -} \ No newline at end of file diff --git a/cmd/protofmt/format.sh b/cmd/protofmt/format.sh deleted file mode 100755 index 367623c..0000000 --- a/cmd/protofmt/format.sh +++ /dev/null @@ -1,4 +0,0 @@ -go install -protofmt unittest_proto2.proto > unittest_proto2_formatted.proto -protofmt unittest_proto3.proto > unittest_proto3_formatted.proto -protofmt unittest_proto3_arena.proto > unittest_proto3_arena_formatted.proto \ No newline at end of file diff --git a/cmd/protofmt/main.go b/cmd/protofmt/main.go deleted file mode 100644 index a203ce2..0000000 --- a/cmd/protofmt/main.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package main - -import ( - "io" - "os" - - "flag" - - "bytes" - "io/ioutil" - - "github.com/emicklei/proto" -) - -var ( - oOverwrite = flag.Bool("w", false, "write result to (source) file instead of stdout") - oDebug = flag.Bool("d", false, "debug mode") -) - -// go run *.go unformatted.proto -func main() { - flag.Parse() - if len(flag.Args()) == 0 { - flag.Usage() - os.Exit(0) - } - exitCode := 0 - for _, each := range flag.Args() { - if err := readFormatWrite(each); err != nil { - println(err.Error()) - exitCode = 1 - } - } - os.Exit(exitCode) -} - -func readFormatWrite(filename string) error { - // open for read - file, err := os.Open(filename) - if err != nil { - return err - } - // buffer before write - buf := new(bytes.Buffer) - if err := format(filename, file, buf); err != nil { - return err - } - if *oOverwrite { - // write back to input - if err := ioutil.WriteFile(filename, buf.Bytes(), os.ModePerm); err != nil { - return err - } - } else { - // write to stdout - if _, err := io.Copy(os.Stdout, bytes.NewReader(buf.Bytes())); err != nil { - return err - } - } - return nil -} - -func format(filename string, input io.Reader, output io.Writer) error { - parser := proto.NewParser(input) - parser.Filename(filename) - def, err := parser.Parse() - if err != nil { - return err - } - // if *oDebug { - // spew.Dump(def) - // } - proto.NewFormatter(output, " ").Format(def) // 2 spaces - return nil -} diff --git a/cmd/protofmt/unittest_proto2.proto b/cmd/protofmt/unittest_proto2.proto deleted file mode 100644 index 0b0c893..0000000 --- a/cmd/protofmt/unittest_proto2.proto +++ /dev/null @@ -1,921 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. - -syntax = "proto2"; - -// Some generic_services option(s) added automatically. -// See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added -option java_generic_services = true; // auto-added -option py_generic_services = true; // auto-added -option cc_enable_arenas = true; - -import "google/protobuf/unittest_import.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; - -option java_outer_classname = "UnittestProto"; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessage optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessage optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnum optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Defined in unittest_import_public.proto - optional protobuf_unittest_import.PublicImportMessage - optional_public_import_message = 26; - - optional NestedMessage optional_lazy_message = 27 [lazy=true]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR ]; - optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum = 83 [default = IMPORT_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; - - // For oneof test - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -// This proto includes a recusively nested message. -message NestedTestAllTypes { - optional NestedTestAllTypes child = 1; - optional TestAllTypes payload = 2; - repeated NestedTestAllTypes repeated_child = 3; -} - -message TestDeprecatedFields { - optional int32 deprecated_int32 = 1 [deprecated=true]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - optional int32 c = 1; - optional int32 d = 2; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestReservedFields { - reserved 2, 15, 9 to 11; - reserved "bar", "baz"; -} - -message TestAllExtensions { - extensions 1 to max; -} - -extend TestAllExtensions { - // Singular - optional int32 optional_int32_extension = 1; - optional int64 optional_int64_extension = 2; - optional uint32 optional_uint32_extension = 3; - optional uint64 optional_uint64_extension = 4; - optional sint32 optional_sint32_extension = 5; - optional sint64 optional_sint64_extension = 6; - optional fixed32 optional_fixed32_extension = 7; - optional fixed64 optional_fixed64_extension = 8; - optional sfixed32 optional_sfixed32_extension = 9; - optional sfixed64 optional_sfixed64_extension = 10; - optional float optional_float_extension = 11; - optional double optional_double_extension = 12; - optional bool optional_bool_extension = 13; - optional string optional_string_extension = 14; - optional bytes optional_bytes_extension = 15; - - optional group OptionalGroup_extension = 16 { - optional int32 a = 17; - } - - optional TestAllTypes.NestedMessage optional_nested_message_extension = 18; - optional ForeignMessage optional_foreign_message_extension = 19; - optional protobuf_unittest_import.ImportMessage - optional_import_message_extension = 20; - - optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21; - optional ForeignEnum optional_foreign_enum_extension = 22; - optional protobuf_unittest_import.ImportEnum - optional_import_enum_extension = 23; - - optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype=CORD]; - - optional protobuf_unittest_import.PublicImportMessage - optional_public_import_message_extension = 26; - - optional TestAllTypes.NestedMessage - optional_lazy_message_extension = 27 [lazy=true]; - - // Repeated - repeated int32 repeated_int32_extension = 31; - repeated int64 repeated_int64_extension = 32; - repeated uint32 repeated_uint32_extension = 33; - repeated uint64 repeated_uint64_extension = 34; - repeated sint32 repeated_sint32_extension = 35; - repeated sint64 repeated_sint64_extension = 36; - repeated fixed32 repeated_fixed32_extension = 37; - repeated fixed64 repeated_fixed64_extension = 38; - repeated sfixed32 repeated_sfixed32_extension = 39; - repeated sfixed64 repeated_sfixed64_extension = 40; - repeated float repeated_float_extension = 41; - repeated double repeated_double_extension = 42; - repeated bool repeated_bool_extension = 43; - repeated string repeated_string_extension = 44; - repeated bytes repeated_bytes_extension = 45; - - repeated group RepeatedGroup_extension = 46 { - optional int32 a = 47; - } - - repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48; - repeated ForeignMessage repeated_foreign_message_extension = 49; - repeated protobuf_unittest_import.ImportMessage - repeated_import_message_extension = 50; - - repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; - repeated ForeignEnum repeated_foreign_enum_extension = 52; - repeated protobuf_unittest_import.ImportEnum - repeated_import_enum_extension = 53; - - repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype=CORD]; - - repeated TestAllTypes.NestedMessage - repeated_lazy_message_extension = 57 [lazy=true]; - - // Singular with defaults - optional int32 default_int32_extension = 61 [default = 41 ]; - optional int64 default_int64_extension = 62 [default = 42 ]; - optional uint32 default_uint32_extension = 63 [default = 43 ]; - optional uint64 default_uint64_extension = 64 [default = 44 ]; - optional sint32 default_sint32_extension = 65 [default = -45 ]; - optional sint64 default_sint64_extension = 66 [default = 46 ]; - optional fixed32 default_fixed32_extension = 67 [default = 47 ]; - optional fixed64 default_fixed64_extension = 68 [default = 48 ]; - optional sfixed32 default_sfixed32_extension = 69 [default = 49 ]; - optional sfixed64 default_sfixed64_extension = 70 [default = -50 ]; - optional float default_float_extension = 71 [default = 51.5 ]; - optional double default_double_extension = 72 [default = 52e3 ]; - optional bool default_bool_extension = 73 [default = true ]; - optional string default_string_extension = 74 [default = "hello"]; - optional bytes default_bytes_extension = 75 [default = "world"]; - - optional TestAllTypes.NestedEnum - default_nested_enum_extension = 81 [default = BAR]; - optional ForeignEnum - default_foreign_enum_extension = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum_extension = 83 [default = IMPORT_BAR]; - - optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, - default="abc"]; - optional string default_cord_extension = 85 [ctype=CORD, default="123"]; - - // For oneof test - optional uint32 oneof_uint32_extension = 111; - optional TestAllTypes.NestedMessage oneof_nested_message_extension = 112; - optional string oneof_string_extension = 113; - optional bytes oneof_bytes_extension = 114; -} - -message TestNestedExtension { - extend TestAllExtensions { - // Check for bug where string extensions declared in tested scope did not - // compile. - optional string test = 1002 [default="test"]; - // Used to test if generated extension name is correct when there are - // underscores. - optional string nested_string_extension = 1003; - } -} - -// We have separate messages for testing required fields because it's -// annoying to have to fill in required fields in TestProto in order to -// do anything with it. Note that we don't need to test every type of -// required filed because the code output is basically identical to -// optional fields for all types. -message TestRequired { - required int32 a = 1; - optional int32 dummy2 = 2; - required int32 b = 3; - - extend TestAllExtensions { - optional TestRequired single = 1000; - repeated TestRequired multi = 1001; - } - - // Pad the field count to 32 so that we can test that IsInitialized() - // properly checks multiple elements of has_bits_. - optional int32 dummy4 = 4; - optional int32 dummy5 = 5; - optional int32 dummy6 = 6; - optional int32 dummy7 = 7; - optional int32 dummy8 = 8; - optional int32 dummy9 = 9; - optional int32 dummy10 = 10; - optional int32 dummy11 = 11; - optional int32 dummy12 = 12; - optional int32 dummy13 = 13; - optional int32 dummy14 = 14; - optional int32 dummy15 = 15; - optional int32 dummy16 = 16; - optional int32 dummy17 = 17; - optional int32 dummy18 = 18; - optional int32 dummy19 = 19; - optional int32 dummy20 = 20; - optional int32 dummy21 = 21; - optional int32 dummy22 = 22; - optional int32 dummy23 = 23; - optional int32 dummy24 = 24; - optional int32 dummy25 = 25; - optional int32 dummy26 = 26; - optional int32 dummy27 = 27; - optional int32 dummy28 = 28; - optional int32 dummy29 = 29; - optional int32 dummy30 = 30; - optional int32 dummy31 = 31; - optional int32 dummy32 = 32; - - required int32 c = 33; -} - -message TestRequiredForeign { - optional TestRequired optional_message = 1; - repeated TestRequired repeated_message = 2; - optional int32 dummy = 3; -} - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - optional TestAllTypes.NestedMessage foreign_nested = 1; -} - -// TestEmptyMessage is used to test unknown field support. -message TestEmptyMessage { -} - -// Like above, but declare all field numbers as potential extensions. No -// actual extensions should ever be defined for this type. -message TestEmptyMessageWithExtensions { - extensions 1 to max; -} - -message TestMultipleExtensionRanges { - extensions 42; - extensions 4143 to 4243; - extensions 65536 to max; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - optional int32 a = 1; - optional int32 bb = 268435455; -} - -message TestRecursiveMessage { - optional TestRecursiveMessage a = 1; - optional int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - optional TestMutualRecursionB bb = 1; -} - -message TestMutualRecursionB { - optional TestMutualRecursionA a = 1; - optional int32 optional_int32 = 2; -} - -// Test that groups have disjoint field numbers from their siblings and -// parents. This is NOT possible in proto1; only google.protobuf. When attempting -// to compile with proto1, this will emit an error; so we only include it -// in protobuf_unittest_proto. -message TestDupFieldNumber { // NO_PROTO1 - optional int32 a = 1; // NO_PROTO1 - optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1 - optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1 -} // NO_PROTO1 - -// Additional messages for testing lazy fields. -message TestEagerMessage { - optional TestAllTypes sub_message = 1 [lazy=false]; -} -message TestLazyMessage { - optional TestAllTypes sub_message = 1 [lazy=true]; -} - -// Needed for a Python test. -message TestNestedMessageHasBits { - message NestedMessage { - repeated int32 nestedmessage_repeated_int32 = 1; - repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2; - } - optional NestedMessage optional_nested_message = 1; -} - - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - option allow_alias = true; - - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - optional int32 PrimitiveField = 1; - optional string StringField = 2; - optional ForeignEnum EnumField = 3; - optional ForeignMessage MessageField = 4; - optional string StringPieceField = 5 [ctype=STRING_PIECE]; - optional string CordField = 6 [ctype=CORD]; - - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; - repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE]; - repeated string RepeatedCordField = 12 [ctype=CORD]; -} - - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - optional string my_string = 11; - extensions 2 to 10; - optional int64 my_int = 1; - extensions 12 to 100; - optional float my_float = 101; - message NestedMessage { - optional int64 oo = 2; - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - optional int32 bb = 1; - } - - optional NestedMessage optional_nested_message = 200; -} - - -extend TestFieldOrderings { - optional string my_extension_string = 50; - optional int32 my_extension_int = 5; -} - - -message TestExtremeDefaultValues { - // NOTE: Unparseable by proto: Go scanner cannot handle some escape chars - // optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; - optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF]; - optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF]; - optional int32 small_int32 = 4 [default = -0x7FFFFFFF]; - optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF]; - optional int32 really_small_int32 = 21 [default = -0x80000000]; - optional int64 really_small_int64 = 22 [default = -0x8000000000000000]; - - // The default value here is UTF-8 for "\u1234". (We could also just type - // the UTF-8 text directly into this text file rather than escape it, but - // lots of people use editors that would be confused by this.) - optional string utf8_string = 6 [default = "\341\210\264"]; - - // Tests for single-precision floating-point values. - optional float zero_float = 7 [default = 0]; - optional float one_float = 8 [default = 1]; - optional float small_float = 9 [default = 1.5]; - optional float negative_one_float = 10 [default = -1]; - optional float negative_float = 11 [default = -1.5]; - // Using exponents - optional float large_float = 12 [default = 2E8]; - optional float small_negative_float = 13 [default = -8e-28]; - - // Text for nonfinite floating-point values. - optional double inf_double = 14 [default = inf]; - optional double neg_inf_double = 15 [default = -inf]; - optional double nan_double = 16 [default = nan]; - optional float inf_float = 17 [default = inf]; - optional float neg_inf_float = 18 [default = -inf]; - optional float nan_float = 19 [default = nan]; - - // Tests for C++ trigraphs. - // Trigraphs should be escaped in C++ generated files, but they should not be - // escaped for other languages. - // Note that in .proto file, "\?" is a valid way to escape ? in string - // literals. - // NOTE: Unparseable by proto: Go scanner cannot handle some escape chars - // optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"]; - - // String defaults containing the character '\000' - optional string string_with_zero = 23 [default = "hel\000lo"]; - optional bytes bytes_with_zero = 24 [default = "wor\000ld"]; - optional string string_piece_with_zero = 25 [ctype=STRING_PIECE, - default="ab\000c"]; - optional string cord_with_zero = 26 [ctype=CORD, - default="12\0003"]; - optional string replacement_string = 27 [default="${unknown}"]; -} - -message SparseEnumMessage { - optional TestSparseEnum sparse_enum = 1; -} - -// Test String and Bytes: string is for valid UTF-8 strings -message OneString { - optional string data = 1; -} - -message MoreString { - repeated string data = 1; -} - -message OneBytes { - optional bytes data = 1; -} - -message MoreBytes { - repeated bytes data = 1; -} - -// Test int32, uint32, int64, uint64, and bool are all compatible -message Int32Message { - optional int32 data = 1; -} - -message Uint32Message { - optional uint32 data = 1; -} - -message Int64Message { - optional int64 data = 1; -} - -message Uint64Message { - optional uint64 data = 1; -} - -message BoolMessage { - optional bool data = 1; -} - -// Test oneofs. -message TestOneof { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - TestAllTypes foo_message = 3; - group FooGroup = 4 { - optional int32 a = 5; - optional string b = 6; - } - } -} - -message TestOneofBackwardsCompatible { - optional int32 foo_int = 1; - optional string foo_string = 2; - optional TestAllTypes foo_message = 3; - optional group FooGroup = 4 { - optional int32 a = 5; - optional string b = 6; - } -} - -message TestOneof2 { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - string foo_cord = 3 [ctype=CORD]; - string foo_string_piece = 4 [ctype=STRING_PIECE]; - bytes foo_bytes = 5; - NestedEnum foo_enum = 6; - NestedMessage foo_message = 7; - group FooGroup = 8 { - optional int32 a = 9; - optional string b = 10; - } - NestedMessage foo_lazy_message = 11 [lazy=true]; - } - - oneof bar { - int32 bar_int = 12 [default = 5]; - string bar_string = 13 [default = "STRING"]; - string bar_cord = 14 [ctype=CORD, default = "CORD"]; - string bar_string_piece = 15 [ctype=STRING_PIECE, default = "SPIECE"]; - bytes bar_bytes = 16 [default = "BYTES"]; - NestedEnum bar_enum = 17 [default = BAR]; - } - - optional int32 baz_int = 18; - optional string baz_string = 19 [default = "BAZ"]; - - message NestedMessage { - optional int64 qux_int = 1; - repeated int32 corge_int = 2; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } -} - -message TestRequiredOneof { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - NestedMessage foo_message = 3; - } - message NestedMessage { - required double required_double = 1; - } -} - - -// Test messages for packed fields - -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// A message with the same fields as TestPackedTypes, but without packing. Used -// to test packed <-> unpacked wire compatibility. -message TestUnpackedTypes { - repeated int32 unpacked_int32 = 90 [packed = false]; - repeated int64 unpacked_int64 = 91 [packed = false]; - repeated uint32 unpacked_uint32 = 92 [packed = false]; - repeated uint64 unpacked_uint64 = 93 [packed = false]; - repeated sint32 unpacked_sint32 = 94 [packed = false]; - repeated sint64 unpacked_sint64 = 95 [packed = false]; - repeated fixed32 unpacked_fixed32 = 96 [packed = false]; - repeated fixed64 unpacked_fixed64 = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; - repeated float unpacked_float = 100 [packed = false]; - repeated double unpacked_double = 101 [packed = false]; - repeated bool unpacked_bool = 102 [packed = false]; - repeated ForeignEnum unpacked_enum = 103 [packed = false]; -} - -message TestPackedExtensions { - extensions 1 to max; -} - -extend TestPackedExtensions { - repeated int32 packed_int32_extension = 90 [packed = true]; - repeated int64 packed_int64_extension = 91 [packed = true]; - repeated uint32 packed_uint32_extension = 92 [packed = true]; - repeated uint64 packed_uint64_extension = 93 [packed = true]; - repeated sint32 packed_sint32_extension = 94 [packed = true]; - repeated sint64 packed_sint64_extension = 95 [packed = true]; - repeated fixed32 packed_fixed32_extension = 96 [packed = true]; - repeated fixed64 packed_fixed64_extension = 97 [packed = true]; - repeated sfixed32 packed_sfixed32_extension = 98 [packed = true]; - repeated sfixed64 packed_sfixed64_extension = 99 [packed = true]; - repeated float packed_float_extension = 100 [packed = true]; - repeated double packed_double_extension = 101 [packed = true]; - repeated bool packed_bool_extension = 102 [packed = true]; - repeated ForeignEnum packed_enum_extension = 103 [packed = true]; -} - -message TestUnpackedExtensions { - extensions 1 to max; -} - -extend TestUnpackedExtensions { - repeated int32 unpacked_int32_extension = 90 [packed = false]; - repeated int64 unpacked_int64_extension = 91 [packed = false]; - repeated uint32 unpacked_uint32_extension = 92 [packed = false]; - repeated uint64 unpacked_uint64_extension = 93 [packed = false]; - repeated sint32 unpacked_sint32_extension = 94 [packed = false]; - repeated sint64 unpacked_sint64_extension = 95 [packed = false]; - repeated fixed32 unpacked_fixed32_extension = 96 [packed = false]; - repeated fixed64 unpacked_fixed64_extension = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32_extension = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64_extension = 99 [packed = false]; - repeated float unpacked_float_extension = 100 [packed = false]; - repeated double unpacked_double_extension = 101 [packed = false]; - repeated bool unpacked_bool_extension = 102 [packed = false]; - repeated ForeignEnum unpacked_enum_extension = 103 [packed = false]; -} - -// Used by ExtensionSetTest/DynamicExtensions. The test actually builds -// a set of extensions to TestAllExtensions dynamically, based on the fields -// of this message type. -message TestDynamicExtensions { - enum DynamicEnumType { - DYNAMIC_FOO = 2200; - DYNAMIC_BAR = 2201; - DYNAMIC_BAZ = 2202; - } - message DynamicMessageType { - optional int32 dynamic_field = 2100; - } - - optional fixed32 scalar_extension = 2000; - optional ForeignEnum enum_extension = 2001; - optional DynamicEnumType dynamic_enum_extension = 2002; - - optional ForeignMessage message_extension = 2003; - optional DynamicMessageType dynamic_message_extension = 2004; - - repeated string repeated_extension = 2005; - repeated sint32 packed_extension = 2006 [packed = true]; -} - -message TestRepeatedScalarDifferentTagSizes { - // Parsing repeated fixed size values used to fail. This message needs to be - // used in order to get a tag of the right size; all of the repeated fields - // in TestAllTypes didn't trigger the check. - repeated fixed32 repeated_fixed32 = 12; - // Check for a varint type, just for good measure. - repeated int32 repeated_int32 = 13; - - // These have two-byte tags. - repeated fixed64 repeated_fixed64 = 2046; - repeated int64 repeated_int64 = 2047; - - // Three byte tags. - repeated float repeated_float = 262142; - repeated uint64 repeated_uint64 = 262143; -} - -// Test that if an optional or required message/group field appears multiple -// times in the input, they need to be merged. -message TestParsingMerge { - // RepeatedFieldsGenerator defines matching field types as TestParsingMerge, - // except that all fields are repeated. In the tests, we will serialize the - // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge. - // Repeated fields in RepeatedFieldsGenerator are expected to be merged into - // the corresponding required/optional fields in TestParsingMerge. - message RepeatedFieldsGenerator { - repeated TestAllTypes field1 = 1; - repeated TestAllTypes field2 = 2; - repeated TestAllTypes field3 = 3; - repeated group Group1 = 10 { - optional TestAllTypes field1 = 11; - } - repeated group Group2 = 20 { - optional TestAllTypes field1 = 21; - } - repeated TestAllTypes ext1 = 1000; - repeated TestAllTypes ext2 = 1001; - } - required TestAllTypes required_all_types = 1; - optional TestAllTypes optional_all_types = 2; - repeated TestAllTypes repeated_all_types = 3; - optional group OptionalGroup = 10 { - optional TestAllTypes optional_group_all_types = 11; - } - repeated group RepeatedGroup = 20 { - optional TestAllTypes repeated_group_all_types = 21; - } - extensions 1000 to max; - extend TestParsingMerge { - optional TestAllTypes optional_ext = 1000; - repeated TestAllTypes repeated_ext = 1001; - } -} - -message TestCommentInjectionMessage { - // */ <- This should not close the generated doc comment - optional string a = 1 [default="*/ <- Neither should this."]; -} - - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} - -message FooClientMessage {} -message FooServerMessage{} - -service TestService { - rpc Foo(FooRequest) returns (FooResponse); - rpc Bar(BarRequest) returns (BarResponse); -} - - -message BarRequest {} -message BarResponse {} - -message TestJsonName { - optional int32 field_name1 = 1; - optional int32 fieldName2 = 2; - optional int32 FieldName3 = 3; - optional int32 _field_name4 = 4; - optional int32 FIELD_NAME5 = 5; - optional int32 field_name6 = 6 [json_name = "@type"]; -} - -message TestHugeFieldNumbers { - optional int32 optional_int32 = 536870000; - optional int32 fixed_32 = 536870001; - repeated int32 repeated_int32 = 536870002 [packed = false]; - repeated int32 packed_int32 = 536870003 [packed = true]; - - optional ForeignEnum optional_enum = 536870004; - optional string optional_string = 536870005; - optional bytes optional_bytes = 536870006; - optional ForeignMessage optional_message = 536870007; - - optional group OptionalGroup = 536870008 { - optional int32 group_a = 536870009; - } - - map string_string_map = 536870010; - - oneof oneof_field { - uint32 oneof_uint32 = 536870011; - TestAllTypes oneof_test_all_types = 536870012; - string oneof_string = 536870013; - bytes oneof_bytes = 536870014; - } - - extensions 536860000 to 536869999; -} - -extend TestHugeFieldNumbers { - optional TestAllTypes test_all_types = 536860000; -} \ No newline at end of file diff --git a/cmd/protofmt/unittest_proto2_formatted.proto b/cmd/protofmt/unittest_proto2_formatted.proto deleted file mode 100644 index e69de29..0000000 diff --git a/cmd/protofmt/unittest_proto3.proto b/cmd/protofmt/unittest_proto3.proto deleted file mode 100644 index dce37be..0000000 --- a/cmd/protofmt/unittest_proto3.proto +++ /dev/null @@ -1,387 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. - -syntax = "proto"; - -// Some generic_services option(s) added automatically. -// See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added -option java_generic_services = true; // auto-added -option py_generic_services = true; // auto-added -option cc_enable_arenas = true; -option csharp_namespace = "Google.Protobuf.TestProtos"; - -import "google/protobuf/unittest_import_proto.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; - -option java_outer_classname = "UnittestProto"; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - - enum NestedEnum { - NESTED_ENUM_UNSPECIFIED = 0; - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - - // Singular - int32 single_int32 = 1; - int64 single_int64 = 2; - uint32 single_uint32 = 3; - uint64 single_uint64 = 4; - sint32 single_sint32 = 5; - sint64 single_sint64 = 6; - fixed32 single_fixed32 = 7; - fixed64 single_fixed64 = 8; - sfixed32 single_sfixed32 = 9; - sfixed64 single_sfixed64 = 10; - float single_float = 11; - double single_double = 12; - bool single_bool = 13; - string single_string = 14; - bytes single_bytes = 15; - - NestedMessage single_nested_message = 18; - ForeignMessage single_foreign_message = 19; - protobuf_unittest_import.ImportMessage single_import_message = 20; - - NestedEnum single_nested_enum = 21; - ForeignEnum single_foreign_enum = 22; - protobuf_unittest_import.ImportEnum single_import_enum = 23; - - // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage - single_public_import_message = 26; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - // Defined in unittest_import_public.proto - repeated protobuf_unittest_import.PublicImportMessage - repeated_public_import_message = 54; - - // For oneof test - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -// This proto includes a recusively nested message. -message NestedTestAllTypes { - NestedTestAllTypes child = 1; - TestAllTypes payload = 2; - repeated NestedTestAllTypes repeated_child = 3; -} - -message TestDeprecatedFields { - int32 deprecated_int32 = 1 [deprecated=true]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_UNSPECIFIED = 0; - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestReservedFields { - reserved 2, 15, 9 to 11; - reserved "bar", "baz"; -} - - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - TestAllTypes.NestedMessage foreign_nested = 1; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - int32 a = 1; - int32 bb = 268435455; -} - -message TestRecursiveMessage { - TestRecursiveMessage a = 1; - int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - TestMutualRecursionB bb = 1; -} - -message TestMutualRecursionB { - TestMutualRecursionA a = 1; - int32 optional_int32 = 2; -} - - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0; - option allow_alias = true; - - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - TEST_SPARSE_ENUM_UNSPECIFIED = 0; - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - // In proto, value 0 must be the first one specified - // SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - int32 PrimitiveField = 1; - string StringField = 2; - ForeignEnum EnumField = 3; - ForeignMessage MessageField = 4; - - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; -} - - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - string my_string = 11; - int64 my_int = 1; - float my_float = 101; - message NestedMessage { - int64 oo = 2; - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - - NestedMessage single_nested_message = 200; -} - -message SparseEnumMessage { - TestSparseEnum sparse_enum = 1; -} - -// Test String and Bytes: string is for valid UTF-8 strings -message OneString { - string data = 1; -} - -message MoreString { - repeated string data = 1; -} - -message OneBytes { - bytes data = 1; -} - -message MoreBytes { - bytes data = 1; -} - -// Test int32, uint32, int64, uint64, and bool are all compatible -message Int32Message { - int32 data = 1; -} - -message Uint32Message { - uint32 data = 1; -} - -message Int64Message { - int64 data = 1; -} - -message Uint64Message { - uint64 data = 1; -} - -message BoolMessage { - bool data = 1; -} - -// Test oneofs. -message TestOneof { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - TestAllTypes foo_message = 3; - } -} - -// Test messages for packed fields - -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// A message with the same fields as TestPackedTypes, but without packing. Used -// to test packed <-> unpacked wire compatibility. -message TestUnpackedTypes { - repeated int32 unpacked_int32 = 90 [packed = false]; - repeated int64 unpacked_int64 = 91 [packed = false]; - repeated uint32 unpacked_uint32 = 92 [packed = false]; - repeated uint64 unpacked_uint64 = 93 [packed = false]; - repeated sint32 unpacked_sint32 = 94 [packed = false]; - repeated sint64 unpacked_sint64 = 95 [packed = false]; - repeated fixed32 unpacked_fixed32 = 96 [packed = false]; - repeated fixed64 unpacked_fixed64 = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; - repeated float unpacked_float = 100 [packed = false]; - repeated double unpacked_double = 101 [packed = false]; - repeated bool unpacked_bool = 102 [packed = false]; - repeated ForeignEnum unpacked_enum = 103 [packed = false]; -} - -message TestRepeatedScalarDifferentTagSizes { - // Parsing repeated fixed size values used to fail. This message needs to be - // used in order to get a tag of the right size; all of the repeated fields - // in TestAllTypes didn't trigger the check. - repeated fixed32 repeated_fixed32 = 12; - // Check for a varint type, just for good measure. - repeated int32 repeated_int32 = 13; - - // These have two-byte tags. - repeated fixed64 repeated_fixed64 = 2046; - repeated int64 repeated_int64 = 2047; - - // Three byte tags. - repeated float repeated_float = 262142; - repeated uint64 repeated_uint64 = 262143; -} - -message TestCommentInjectionMessage { - // */ <- This should not close the generated doc comment - string a = 1; -} - - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} - -message FooClientMessage {} -message FooServerMessage{} - -service TestService { - rpc Foo(FooRequest) returns (FooResponse); - rpc Bar(BarRequest) returns (BarResponse); -} - - -message BarRequest {} -message BarResponse {} diff --git a/cmd/protofmt/unittest_proto3_arena.proto b/cmd/protofmt/unittest_proto3_arena.proto deleted file mode 100644 index 9dc31ae..0000000 --- a/cmd/protofmt/unittest_proto3_arena.proto +++ /dev/null @@ -1,205 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto"; - -option cc_enable_arenas = true; - -import "google/protobuf/unittest_import.proto"; - -package proto_arena_unittest; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - - enum NestedEnum { - ZERO = 0; - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - - // Singular - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; - sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; - - // Groups are not allowed in proto. - // optional group OptionalGroup = 16 { - // optional int32 a = 17; - // } - - NestedMessage optional_nested_message = 18; - ForeignMessage optional_foreign_message = 19; - protobuf_unittest_import.ImportMessage optional_import_message = 20; - - NestedEnum optional_nested_enum = 21; - ForeignEnum optional_foreign_enum = 22; - - // Omitted (compared to unittest.proto) because proto2 enums are not allowed - // inside proto2 messages. - // - // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - - string optional_string_piece = 24 [ctype=STRING_PIECE]; - string optional_cord = 25 [ctype=CORD]; - - // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage - optional_public_import_message = 26; - - NestedMessage optional_lazy_message = 27 [lazy=true]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - // Groups are not allowed in proto. - // repeated group RepeatedGroup = 46 { - // optional int32 a = 47; - // } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - - // Omitted (compared to unittest.proto) because proto2 enums are not allowed - // inside proto2 messages. - // - // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -// Test messages for packed fields - -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// Explicitly set packed to false -message TestUnpackedTypes { - repeated int32 repeated_int32 = 1 [packed = false]; - repeated int64 repeated_int64 = 2 [packed = false]; - repeated uint32 repeated_uint32 = 3 [packed = false]; - repeated uint64 repeated_uint64 = 4 [packed = false]; - repeated sint32 repeated_sint32 = 5 [packed = false]; - repeated sint64 repeated_sint64 = 6 [packed = false]; - repeated fixed32 repeated_fixed32 = 7 [packed = false]; - repeated fixed64 repeated_fixed64 = 8 [packed = false]; - repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; - repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; - repeated float repeated_float = 11 [packed = false]; - repeated double repeated_double = 12 [packed = false]; - repeated bool repeated_bool = 13 [packed = false]; - repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; -} - -// This proto includes a recusively nested message. -message NestedTestAllTypes { - NestedTestAllTypes child = 1; - TestAllTypes payload = 2; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_ZERO = 0; - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -// TestEmptyMessage is used to test behavior of unknown fields. -message TestEmptyMessage { -} diff --git a/cmd/protofmt/unittest_proto3_arena_formatted.proto b/cmd/protofmt/unittest_proto3_arena_formatted.proto deleted file mode 100644 index 33398e4..0000000 --- a/cmd/protofmt/unittest_proto3_arena_formatted.proto +++ /dev/null @@ -1,185 +0,0 @@ - -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -syntax = "proto"; - -option cc_enable_arenas = true; -import "google/protobuf/unittest_import.proto"; - -package proto_arena_unittest; - - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - enum NestedEnum { - ZERO = 0; - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - // Singular - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; - sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; - // Groups are not allowed in proto. - // optional group OptionalGroup = 16 { - // optional int32 a = 17; - // } - NestedMessage optional_nested_message = 18; - ForeignMessage optional_foreign_message = 19; - protobuf_unittest_import.ImportMessage optional_import_message = 20; - NestedEnum optional_nested_enum = 21; - ForeignEnum optional_foreign_enum = 22; - // Omitted (compared to unittest.proto) because proto2 enums are not allowed - // inside proto2 messages. - - // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - string optional_string_piece = 24 [ctype = STRING_PIECE]; - string optional_cord = 25 [ctype = CORD ]; - // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26; - NestedMessage optional_lazy_message = 27 [lazy = true]; - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - // Groups are not allowed in proto. - // repeated group RepeatedGroup = 46 { - // optional int32 a = 47; - // } - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - // Omitted (compared to unittest.proto) because proto2 enums are not allowed - // inside proto2 messages. - - // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - repeated string repeated_string_piece = 54 [ctype = STRING_PIECE]; - repeated string repeated_cord = 55 [ctype = CORD ]; - repeated NestedMessage repeated_lazy_message = 57 [lazy = true ]; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -// Test messages for packed fields -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// Explicitly set packed to false -message TestUnpackedTypes { - repeated int32 repeated_int32 = 1 [packed = false]; - repeated int64 repeated_int64 = 2 [packed = false]; - repeated uint32 repeated_uint32 = 3 [packed = false]; - repeated uint64 repeated_uint64 = 4 [packed = false]; - repeated sint32 repeated_sint32 = 5 [packed = false]; - repeated sint64 repeated_sint64 = 6 [packed = false]; - repeated fixed32 repeated_fixed32 = 7 [packed = false]; - repeated fixed64 repeated_fixed64 = 8 [packed = false]; - repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; - repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; - repeated float repeated_float = 11 [packed = false]; - repeated double repeated_double = 12 [packed = false]; - repeated bool repeated_bool = 13 [packed = false]; - repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; -} - -// This proto includes a recusively nested message. -message NestedTestAllTypes { - NestedTestAllTypes child = 1; - TestAllTypes payload = 2; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - int32 c = 1; -} -enum ForeignEnum { - FOREIGN_ZERO = 0; - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -// TestEmptyMessage is used to test behavior of unknown fields. -message TestEmptyMessage {} diff --git a/cmd/protofmt/unittest_proto3_formatted.proto b/cmd/protofmt/unittest_proto3_formatted.proto deleted file mode 100644 index 340c35c..0000000 --- a/cmd/protofmt/unittest_proto3_formatted.proto +++ /dev/null @@ -1,349 +0,0 @@ - -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. -syntax = "proto"; - - -// Some generic_services option(s) added automatically. -// See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added -option java_generic_services = true; // auto-added -option py_generic_services = true; // auto-added -option cc_enable_arenas = true; -option csharp_namespace = "Google.Protobuf.TestProtos"; -import "google/protobuf/unittest_import_proto.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; -option java_outer_classname = "UnittestProto"; - - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - enum NestedEnum { - NESTED_ENUM_UNSPECIFIED = 0; - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - // Singular - int32 single_int32 = 1; - int64 single_int64 = 2; - uint32 single_uint32 = 3; - uint64 single_uint64 = 4; - sint32 single_sint32 = 5; - sint64 single_sint64 = 6; - fixed32 single_fixed32 = 7; - fixed64 single_fixed64 = 8; - sfixed32 single_sfixed32 = 9; - sfixed64 single_sfixed64 = 10; - float single_float = 11; - double single_double = 12; - bool single_bool = 13; - string single_string = 14; - bytes single_bytes = 15; - NestedMessage single_nested_message = 18; - ForeignMessage single_foreign_message = 19; - protobuf_unittest_import.ImportMessage single_import_message = 20; - NestedEnum single_nested_enum = 21; - ForeignEnum single_foreign_enum = 22; - protobuf_unittest_import.ImportEnum single_import_enum = 23; - // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage single_public_import_message = 26; - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - // Defined in unittest_import_public.proto - repeated protobuf_unittest_import.PublicImportMessage repeated_public_import_message = 54; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -// This proto includes a recusively nested message. -message NestedTestAllTypes { - NestedTestAllTypes child = 1; - TestAllTypes payload = 2; - repeated NestedTestAllTypes repeated_child = 3; -} -message TestDeprecatedFields { - int32 deprecated_int32 = 1 [deprecated = true]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - int32 c = 1; -} -enum ForeignEnum { - FOREIGN_UNSPECIFIED = 0; - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} -message TestReservedFields { - reserved 2, 15, 9 to 11; - reserved "bar", "baz"; -} - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - TestAllTypes.NestedMessage foreign_nested = 1; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - int32 a = 1; - int32 bb = 268435455; -} -message TestRecursiveMessage { - TestRecursiveMessage a = 1; - int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - TestMutualRecursionB bb = 1; -} -message TestMutualRecursionB { - TestMutualRecursionA a = 1; - int32 optional_int32 = 2; -} - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0; - option allow_alias = true; - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - TEST_SPARSE_ENUM_UNSPECIFIED = 0; - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - // In proto, value 0 must be the first one specified - // SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - int32 PrimitiveField = 1; - string StringField = 2; - ForeignEnum EnumField = 3; - ForeignMessage MessageField = 4; - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; -} - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - string my_string = 11; - int64 my_int = 1; - float my_float = 101; - message NestedMessage { - int64 oo = 2; - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - NestedMessage single_nested_message = 200; -} -message SparseEnumMessage { - TestSparseEnum sparse_enum = 1; -} - -// Test String and Bytes: string is for valid UTF-8 strings -message OneString { - string data = 1; -} -message MoreString { - repeated string data = 1; -} -message OneBytes { - bytes data = 1; -} -message MoreBytes { - bytes data = 1; -} - -// Test int32, uint32, int64, uint64, and bool are all compatible -message Int32Message { - int32 data = 1; -} -message Uint32Message { - uint32 data = 1; -} -message Int64Message { - int64 data = 1; -} -message Uint64Message { - uint64 data = 1; -} -message BoolMessage { - bool data = 1; -} - -// Test oneofs. -message TestOneof { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - TestAllTypes foo_message = 3; - } -} - -// Test messages for packed fields -message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; -} - -// A message with the same fields as TestPackedTypes, but without packing. Used -// to test packed <-> unpacked wire compatibility. -message TestUnpackedTypes { - repeated int32 unpacked_int32 = 90 [packed = false]; - repeated int64 unpacked_int64 = 91 [packed = false]; - repeated uint32 unpacked_uint32 = 92 [packed = false]; - repeated uint64 unpacked_uint64 = 93 [packed = false]; - repeated sint32 unpacked_sint32 = 94 [packed = false]; - repeated sint64 unpacked_sint64 = 95 [packed = false]; - repeated fixed32 unpacked_fixed32 = 96 [packed = false]; - repeated fixed64 unpacked_fixed64 = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; - repeated float unpacked_float = 100 [packed = false]; - repeated double unpacked_double = 101 [packed = false]; - repeated bool unpacked_bool = 102 [packed = false]; - repeated ForeignEnum unpacked_enum = 103 [packed = false]; -} -message TestRepeatedScalarDifferentTagSizes { - // Parsing repeated fixed size values used to fail. This message needs to be - // used in order to get a tag of the right size; all of the repeated fields - // in TestAllTypes didn't trigger the check. - repeated fixed32 repeated_fixed32 = 12; - // Check for a varint type, just for good measure. - repeated int32 repeated_int32 = 13; - // These have two-byte tags. - repeated fixed64 repeated_fixed64 = 2046; - repeated int64 repeated_int64 = 2047; - // Three byte tags. - repeated float repeated_float = 262142; - repeated uint64 repeated_uint64 = 262143; -} -message TestCommentInjectionMessage { - // */ <- This should not close the generated doc comment - string a = 1; -} - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} -message FooClientMessage {} -message FooServerMessage {} - -service TestService { - rpc Foo (FooRequest) returns (FooResponse); - rpc Bar (BarRequest) returns (BarResponse); -} -message BarRequest {} -message BarResponse {} diff --git a/comment.go b/comment.go index 7b74e6f..9e27920 100644 --- a/comment.go +++ b/comment.go @@ -57,38 +57,11 @@ func newComment(pos scanner.Position, lit string) *Comment { return &Comment{Position: pos, Lines: nonEmpty, Cstyle: len(lines) > 1, ExtraSlash: extraSlash} } -// columns is part of columnsPrintable -func (c *Comment) columnsPrintables() (list []columnsPrintable) { - for _, each := range c.Lines { - list = append(list, inlineComment{each, c.ExtraSlash}) - } - return -} - -func (c *Comment) alignedInlinePrefix() aligned { - prefix := " //" - if c.ExtraSlash { - prefix = " ///" - } - return notAligned(prefix) -} - type inlineComment struct { line string extraSlash bool } -func (i inlineComment) columns() (list []aligned) { - if len(i.line) == 0 { - return append(list, notAligned("")) - } - prefix := "//" - if i.extraSlash { - prefix = "///" - } - return append(list, notAligned(prefix+i.line)) -} - // Accept dispatches the call to the visitor. func (c *Comment) Accept(v Visitor) { v.VisitComment(c) diff --git a/enum.go b/enum.go index efec281..c51f98b 100644 --- a/enum.go +++ b/enum.go @@ -24,7 +24,6 @@ package proto import ( - "strconv" "text/scanner" ) @@ -139,19 +138,6 @@ func (f *EnumField) Doc() *Comment { return f.Comment } -// columns returns printable source tokens -func (f EnumField) columns() (cols []aligned) { - cols = append(cols, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Integer))) - if f.ValueOption != nil { - cols = append(cols, f.ValueOption.columns()...) - } - cols = append(cols, alignedSemicolon) - if f.InlineComment != nil { - cols = append(cols, f.InlineComment.alignedInlinePrefix(), notAligned(f.InlineComment.Message())) - } - return -} - func (f *EnumField) parse(p *Parser) error { _, tok, lit := p.nextIdentifier() if tok != tIDENT { diff --git a/field.go b/field.go index c03ea38..efe2c88 100644 --- a/field.go +++ b/field.go @@ -24,7 +24,6 @@ package proto import ( - "strconv" "text/scanner" ) @@ -64,36 +63,6 @@ func (f *NormalField) Doc() *Comment { return f.Comment } -// columns returns printable source tokens -func (f *NormalField) columns() (cols []aligned) { - if f.Repeated { - cols = append(cols, leftAligned("repeated ")) - } else { - cols = append(cols, alignedEmpty) - } - if f.Optional { - cols = append(cols, leftAligned("optional ")) - } else { - cols = append(cols, alignedEmpty) - } - cols = append(cols, rightAligned(f.Type), alignedSpace, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Sequence))) - if len(f.Options) > 0 { - cols = append(cols, leftAligned(" [")) - for i, each := range f.Options { - if i > 0 { - cols = append(cols, alignedComma) - } - cols = append(cols, each.keyValuePair(true)...) - } - cols = append(cols, leftAligned("]")) - } - cols = append(cols, alignedSemicolon) - if f.InlineComment != nil { - cols = append(cols, f.InlineComment.alignedInlinePrefix(), notAligned(f.InlineComment.Message())) - } - return -} - // parse expects: // [ "repeated" | "optional" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" func (f *NormalField) parse(p *Parser) error { @@ -177,34 +146,6 @@ func (f *MapField) Accept(v Visitor) { v.VisitMapField(f) } -// columns returns printable source tokens -func (f *MapField) columns() (cols []aligned) { - cols = append(cols, - notAligned("map <"), - rightAligned(f.KeyType), - notAligned(","), - leftAligned(f.Type), - notAligned("> "), - rightAligned(f.Name), - alignedEquals, - rightAligned(strconv.Itoa(f.Sequence))) - if len(f.Options) > 0 { - cols = append(cols, leftAligned(" [")) - for i, each := range f.Options { - if i > 0 { - cols = append(cols, alignedComma) - } - cols = append(cols, each.keyValuePair(true)...) - } - cols = append(cols, leftAligned("]")) - } - cols = append(cols, alignedSemicolon) - if f.InlineComment != nil { - cols = append(cols, f.InlineComment.alignedInlinePrefix(), notAligned(f.InlineComment.Message())) - } - return -} - // parse expects: // mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" // keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | diff --git a/formatter.go b/formatter.go deleted file mode 100644 index 5b8c0f7..0000000 --- a/formatter.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package proto - -import ( - "fmt" - "io" -) - -// Formatter visits a Proto and writes formatted source. -type Formatter struct { - w io.Writer - indentSeparator string - indentLevel int - lastStmt string - lastLevel int -} - -// NewFormatter returns a new Formatter. Only the indentation separator is configurable. -func NewFormatter(writer io.Writer, indentSeparator string) *Formatter { - return &Formatter{w: writer, indentSeparator: indentSeparator} -} - -// Format visits all proto elements and writes formatted source. -func (f *Formatter) Format(p *Proto) { - for _, each := range p.Elements { - each.Accept(f) - } -} - -// VisitComment formats a Comment and writes a newline. -func (f *Formatter) VisitComment(c *Comment) { - f.printComment(c) - f.nl() -} - -// VisitEnum formats a Enum. -func (f *Formatter) VisitEnum(e *Enum) { - f.begin("enum", e) - fmt.Fprintf(f.w, "enum %s {", e.Name) - if len(e.Elements) > 0 { - f.nl() - f.level(1) - f.printAsGroups(e.Elements) - f.indent(-1) - } - io.WriteString(f.w, "}\n") - f.end("enum") -} - -// VisitEnumField formats a EnumField. -func (f *Formatter) VisitEnumField(e *EnumField) { - f.printAsGroups([]Visitee{e}) -} - -// VisitImport formats a Import. -func (f *Formatter) VisitImport(i *Import) { - f.printAsGroups([]Visitee{i}) -} - -// VisitMessage formats a Message. -func (f *Formatter) VisitMessage(m *Message) { - f.begin("message", m) - if m.IsExtend { - fmt.Fprintf(f.w, "extend ") - } else { - fmt.Fprintf(f.w, "message ") - } - fmt.Fprintf(f.w, "%s {", m.Name) - if len(m.Elements) > 0 { - f.nl() - f.level(1) - f.printAsGroups(m.Elements) - f.indent(-1) - } - io.WriteString(f.w, "}\n") - f.end("message") -} - -// VisitOption formats a Option. -func (f *Formatter) VisitOption(o *Option) { - f.begin("option", o) - fmt.Fprintf(f.w, "option %s = ", o.Name) - if o.AggregatedConstants != nil { - fmt.Fprintf(f.w, "{\n") - f.level(1) - for _, each := range o.AggregatedConstants { - f.indent(0) - fmt.Fprintf(f.w, "%s: %s\n", each.Name, each.Literal.SourceRepresentation()) - } - f.indent(-1) - fmt.Fprintf(f.w, "}") - } else { - // TODO printAs groups with fixed length - fmt.Fprintf(f.w, o.Constant.SourceRepresentation()) - } - fmt.Fprintf(f.w, ";") - if o.InlineComment != nil { - fmt.Fprintf(f.w, " //%s", o.InlineComment.Message()) - } - f.nl() -} - -// VisitPackage formats a Package. -func (f *Formatter) VisitPackage(p *Package) { - f.nl() - f.printAsGroups([]Visitee{p}) -} - -// VisitService formats a Service. -func (f *Formatter) VisitService(s *Service) { - f.begin("service", s) - fmt.Fprintf(f.w, "service %s {", s.Name) - if len(s.Elements) > 0 { - f.nl() - f.level(1) - f.printAsGroups(s.Elements) - f.indent(-1) - } - io.WriteString(f.w, "}\n") - f.end("service") -} - -// VisitSyntax formats a Syntax. -func (f *Formatter) VisitSyntax(s *Syntax) { - f.begin("syntax", s) - fmt.Fprintf(f.w, "syntax = %q", s.Value) - f.endWithComment(s.InlineComment) -} - -// VisitOneof formats a Oneof. -func (f *Formatter) VisitOneof(o *Oneof) { - f.begin("oneof", o) - fmt.Fprintf(f.w, "oneof %s {", o.Name) - if len(o.Elements) > 0 { - f.nl() - f.level(1) - f.printAsGroups(o.Elements) - f.indent(-1) - } - io.WriteString(f.w, "}\n") - f.end("oneof") -} - -// VisitOneofField formats a OneofField. -func (f *Formatter) VisitOneofField(o *OneOfField) { - f.printAsGroups([]Visitee{o}) -} - -// VisitReserved formats a Reserved. -func (f *Formatter) VisitReserved(r *Reserved) { - f.begin("reserved", r) - io.WriteString(f.w, "reserved ") - if len(r.Ranges) > 0 { - for i, each := range r.Ranges { - if i > 0 { - io.WriteString(f.w, ", ") - } - fmt.Fprintf(f.w, "%s", each.SourceRepresentation()) - } - } else { - for i, each := range r.FieldNames { - if i > 0 { - io.WriteString(f.w, ", ") - } - fmt.Fprintf(f.w, "%q", each) - } - } - f.endWithComment(r.InlineComment) -} - -// VisitRPC formats a RPC. -func (f *Formatter) VisitRPC(r *RPC) { - f.printAsGroups([]Visitee{r}) -} - -// VisitMapField formats a MapField. -func (f *Formatter) VisitMapField(m *MapField) { - f.printAsGroups([]Visitee{m}) -} - -// VisitNormalField formats a NormalField. -func (f *Formatter) VisitNormalField(f1 *NormalField) { - f.printAsGroups([]Visitee{f1}) -} - -// VisitGroup formats a proto2 Group. -func (f *Formatter) VisitGroup(g *Group) { - f.begin("group", g) - if g.Optional { - io.WriteString(f.w, "optional ") - } - fmt.Fprintf(f.w, "group %s = %d {", g.Name, g.Sequence) - if len(g.Elements) > 0 { - f.nl() - f.level(1) - f.printAsGroups(g.Elements) - f.indent(-1) - } - io.WriteString(f.w, "}\n") - f.end("group") -} - -// VisitExtensions formats a proto2 Extensions. -func (f *Formatter) VisitExtensions(e *Extensions) { - f.begin("extensions", e) - io.WriteString(f.w, "extensions ") - for i, each := range e.Ranges { - if i > 0 { - io.WriteString(f.w, ", ") - } - fmt.Fprintf(f.w, "%s", each.SourceRepresentation()) - } - f.endWithComment(e.InlineComment) -} diff --git a/formatter_test.go b/formatter_test.go deleted file mode 100644 index ab3bffd..0000000 --- a/formatter_test.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package proto - -import ( - "bytes" - "fmt" - "strings" - "testing" -) - -func TestPrintListOfColumns(t *testing.T) { - e0 := new(EnumField) - e0.Name = "A" - e0.Integer = 1 - op0 := new(Option) - op0.IsEmbedded = true - op0.Name = "a" - op0.Constant = Literal{Source: "1234"} - e0.ValueOption = op0 - - e1 := new(EnumField) - e1.Name = "ABC" - e1.Integer = 12 - op1 := new(Option) - op1.IsEmbedded = true - op1.Name = "ab" - op1.Constant = Literal{Source: "1234"} - e1.ValueOption = op1 - - list := []columnsPrintable{e0, e1} - b := new(bytes.Buffer) - f := NewFormatter(b, " ") - f.printListOfColumns(list) - formatted := `A = 1 [a = 1234]; -ABC = 12 [ab = 1234]; -` - if got, want := b.String(), formatted; got != want { - t.Errorf("got [%v] want [%v]", got, want) - } -} - -func TestFormatCStyleComment(t *testing.T) { - t.Skip() - proto := `/* - * Hello - * World - */ -` - def, _ := NewParser(strings.NewReader(proto)).Parse() - b := new(bytes.Buffer) - f := NewFormatter(b, " ") - f.Format(def) - if got, want := proto, formatted(def.Elements[0]); got != want { - println(diff(got, want)) - t.Fail() - } -} - -func TestFormatExtendMessage(t *testing.T) { - t.Skip() - proto := ` -// extend -extend google.protobuf.MessageOptions { - // my_option - optional string my_option = 51234; // mynumber -} -` - p := newParserOn(proto) - pp, err := p.Parse() - if err != nil { - t.Fatal(err) - } - m, ok := pp.Elements[0].(*Message) - if !ok { - t.Fatal("message expected") - } - if got, want := formatted(m), proto; got != want { - fmt.Println(diff(got, want)) - fmt.Println(got) - t.Fail() - } -} - -func TestFormatAggregatedOptionSyntax(t *testing.T) { - // TODO format not that nice - proto := `rpc Find (Finder) returns (stream Result) { - option (google.api.http) = { - post: "/v1/finders/1" - body: "*" - }; - -} -` - p := newParserOn(proto) - r := new(RPC) - p.next() // consumer rpc - err := r.parse(p) - if err != nil { - t.Fatal(err) - } - if got, want := formatted(r), proto; got != want { - fmt.Println(diff(got, want)) - fmt.Println("---") - fmt.Println(got) - fmt.Println("---") - fmt.Println(want) - t.Fail() - } -} - -func TestFormatCommentSample(t *testing.T) { - proto := ` -/* - begin -*/ - -// comment 1 -// comment 2 -syntax = "proto"; // inline 1 - -// comment 3 -// comment 4 -package test; // inline 2 - -// comment 5 -// comment 6 -message Test { - // comment 7 - // comment 8 - int64 i = 1; // inline 3 -} -/// triple -` - p := newParserOn(proto) - def, err := p.Parse() - if err != nil { - t.Fatal(err) - } - if got, want := len(def.Elements), 5; got != want { - t.Fatalf("got [%v] want [%v]", got, want) - } - b := new(bytes.Buffer) - f := NewFormatter(b, " ") // 2 spaces - f.Format(def) - //println(b.String()) - //spew.Dump(def) -} - -/// testing utils -func formatted(v Visitee) string { - b := new(bytes.Buffer) - f := NewFormatter(b, " ") // 2 spaces - v.Accept(f) - return b.String() -} - -func diff(left, right string) string { - b := new(bytes.Buffer) - w := func(char rune) { - if '\n' == char { - b.WriteString("(n)") - } else if '\t' == char { - b.WriteString("(t)") - } else if ' ' == char { - b.WriteString("( )") - } else { - b.WriteRune(char) - } - } - b.WriteString("got:\n") - for _, char := range left { - w(char) - } - if len(left) == 0 { - b.WriteString("(empty)") - } - b.WriteString("\n") - for _, char := range right { - w(char) - } - b.WriteString("\n:wanted\n") - return b.String() -} diff --git a/formatter_utils.go b/formatter_utils.go deleted file mode 100644 index 83ce262..0000000 --- a/formatter_utils.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package proto - -import ( - "fmt" - "io" -) - -// printDoc writes documentation is available -func (f *Formatter) printDoc(v Visitee) { - if hasDoc, ok := v.(Documented); ok { - if doc := hasDoc.Doc(); doc != nil { - f.printComment(doc) - } - } -} - -// printComment formats a Comment. -func (f *Formatter) printComment(c *Comment) { - f.nl() - if c.Cstyle { - fmt.Fprintln(f.w, "/*") - } - for i, each := range c.Lines { - f.indent(0) - if c.Cstyle { - // only skip first and last empty lines - skip := (i == 0 && len(each) == 0) || - (i == len(c.Lines)-1 && len(each) == 0) - if !skip { - fmt.Fprintf(f.w, "%s\n", each) - } - } else { - if c.ExtraSlash { - fmt.Fprint(f.w, "/") - } - fmt.Fprintf(f.w, "//%s\n", each) - } - } - if c.Cstyle { - fmt.Fprintf(f.w, " */\n") - } -} - -// begin writes a newline if the last statement kind is different. always indents. -// if the Visitee has comment then print it. -func (f *Formatter) begin(stmt string, v Visitee) { - // if not the first statement and different from last and on same indent level. - if len(f.lastStmt) > 0 && f.lastStmt != stmt && f.lastLevel == f.indentLevel { - f.nl() - } - f.lastStmt = stmt - f.printDoc(v) - f.indent(0) -} - -func (f *Formatter) end(stmt string) { - f.lastStmt = stmt -} - -// indent changes the indent level and writes indentation. -func (f *Formatter) indent(diff int) { - f.level(diff) - for i := 0; i < f.indentLevel; i++ { - io.WriteString(f.w, f.indentSeparator) - } -} - -// columnsPrintable is for elements that can be printed in aligned columns. -type columnsPrintable interface { - columns() (cols []aligned) - //doc() *Comment -} - -func (f *Formatter) printListOfColumns(list []columnsPrintable) { - if len(list) == 0 { - return - } - // collect all column values - values := [][]aligned{} - widths := map[int]int{} - for _, each := range list { - cols := each.columns() - values = append(values, cols) - // update max widths per column - for i, other := range cols { - pw := other.preferredWidth() - w, ok := widths[i] - if ok { - if pw > w { - widths[i] = pw - } - } else { - widths[i] = pw - } - } - } - // now print all values - for _, each := range values { - f.indent(0) - for c := 0; c < len(widths); c++ { - pw := widths[c] - // only print if there is a value - if c < len(each) { - // using space padding to match the max width - io.WriteString(f.w, each[c].formatted(f.indentSeparator, f.indentLevel, pw)) - } - } - f.nl() - } -} - -// nl writes a newline. -func (f *Formatter) nl() { - io.WriteString(f.w, "\n") -} - -// level changes the current indentLevel -func (f *Formatter) level(diff int) { - f.lastLevel = f.indentLevel - f.indentLevel += diff -} - -// printAsGroups prints the list in groups of the same element type. -func (f *Formatter) printAsGroups(list []Visitee) { - group := []columnsPrintable{} - lastGroupName := "" - for _, each := range list { - groupName := nameOfVisitee(each) - printable, isColumnsPrintable := each.(columnsPrintable) - if isColumnsPrintable { - if lastGroupName != groupName { - lastGroupName = groupName - // print current group - if len(group) > 0 { - f.printListOfColumns(group) - // begin new group - group = []columnsPrintable{} - } - } - // comment as a group entity - if hasDoc, ok := each.(Documented); ok { - if doc := hasDoc.Doc(); doc != nil { - f.printListOfColumns(group) - // begin new group - group = append([]columnsPrintable{}, doc.columnsPrintables()...) - } - } - group = append(group, printable) - } else { - // not printable in group - lastGroupName = groupName - // print current group - if len(group) > 0 { - f.printListOfColumns(group) - // begin new group - group = []columnsPrintable{} - } - each.Accept(f) - } - } - // print last group - f.printListOfColumns(group) -} - -// endWithComment writes a statement end (;) followed by inline comment if present. -func (f *Formatter) endWithComment(commentOrNil *Comment) { - io.WriteString(f.w, ";") - if commentOrNil != nil { - if commentOrNil.ExtraSlash { - io.WriteString(f.w, " ///") - } else { - io.WriteString(f.w, " //") - } - io.WriteString(f.w, commentOrNil.Message()) - } - io.WriteString(f.w, "\n") -} diff --git a/import.go b/import.go index a318b12..fe978ca 100644 --- a/import.go +++ b/import.go @@ -24,7 +24,6 @@ package proto import ( - "fmt" "text/scanner" ) @@ -68,16 +67,3 @@ func (i *Import) inlineComment(c *Comment) { func (i *Import) Doc() *Comment { return i.Comment } - -// columns returns printable source tokens -func (i *Import) columns() (cols []aligned) { - cols = append(cols, leftAligned("import"), alignedSpace) - if len(i.Kind) > 0 { - cols = append(cols, leftAligned(i.Kind), alignedSpace) - } - cols = append(cols, notAligned(fmt.Sprintf("%q", i.Filename)), alignedSemicolon) - if i.InlineComment != nil { - cols = append(cols, notAligned(" //"), notAligned(i.InlineComment.Message())) - } - return -} diff --git a/oneof.go b/oneof.go index ce6a239..2fad150 100644 --- a/oneof.go +++ b/oneof.go @@ -24,7 +24,6 @@ package proto import ( - "strconv" "text/scanner" ) @@ -127,28 +126,3 @@ func (o *OneOfField) Accept(v Visitor) { func (o *OneOfField) Doc() *Comment { return o.Comment } - -// columns returns printable source tokens -func (o *OneOfField) columns() (cols []aligned) { - cols = append(cols, - rightAligned(o.Type), - alignedSpace, - leftAligned(o.Name), - alignedEquals, - rightAligned(strconv.Itoa(o.Sequence))) - if len(o.Options) > 0 { - cols = append(cols, leftAligned(" [")) - for i, each := range o.Options { - if i > 0 { - cols = append(cols, alignedComma) - } - cols = append(cols, each.keyValuePair(true)...) - } - cols = append(cols, leftAligned("]")) - } - cols = append(cols, alignedSemicolon) - if o.InlineComment != nil { - cols = append(cols, notAligned(" //"), notAligned(o.InlineComment.Message())) - } - return -} diff --git a/option.go b/option.go index 3a7229a..31ef9d8 100644 --- a/option.go +++ b/option.go @@ -40,36 +40,6 @@ type Option struct { InlineComment *Comment } -// columns returns printable source tokens -func (o *Option) columns() (cols []aligned) { - if !o.IsEmbedded { - cols = append(cols, leftAligned("option ")) - } else { - cols = append(cols, leftAligned(" [")) - } - cols = append(cols, o.keyValuePair(o.IsEmbedded)...) - if o.IsEmbedded { - cols = append(cols, leftAligned("]")) - } - if !o.IsEmbedded { - cols = append(cols, alignedSemicolon) - if o.InlineComment != nil { - cols = append(cols, notAligned(" //"), notAligned(o.InlineComment.Message())) - } - } - return -} - -// keyValuePair returns key = value or "value" -func (o *Option) keyValuePair(embedded bool) (cols []aligned) { - equals := alignedEquals - name := o.Name - if embedded { - return append(cols, leftAligned(name), equals, leftAligned(o.Constant.SourceRepresentation())) // numbers right, strings left? TODO - } - return append(cols, rightAligned(name), equals, rightAligned(o.Constant.SourceRepresentation())) -} - // parse reads an Option body // ( ident | "(" fullIdent ")" ) { "." ident } "=" constant ";" func (o *Option) parse(p *Parser) error { diff --git a/package.go b/package.go index b84c402..c51390b 100644 --- a/package.go +++ b/package.go @@ -58,12 +58,3 @@ func (p *Package) Accept(v Visitor) { func (p *Package) inlineComment(c *Comment) { p.InlineComment = c } - -// columns returns printable source tokens -func (p *Package) columns() (cols []aligned) { - cols = append(cols, notAligned("package "), notAligned(p.Name), alignedSemicolon) - if p.InlineComment != nil { - cols = append(cols, notAligned(" //"), notAligned(p.InlineComment.Message())) - } - return -} diff --git a/parser.go b/parser.go index 3657a98..d967853 100644 --- a/parser.go +++ b/parser.go @@ -114,7 +114,7 @@ func (p *Parser) unexpected(found, expected string, obj interface{}) error { _, file, line, _ := runtime.Caller(1) debug = fmt.Sprintf(" at %s:%d (with %#v)", file, line, obj) } - return fmt.Errorf("%v: Found %q but expected [%s]%s.", p.scanner.Position, found, expected, debug) + return fmt.Errorf("%v: found %q but expected [%s]%s", p.scanner.Position, found, expected, debug) } func (p *Parser) nextInteger() (i int, err error) { diff --git a/proto_test.go b/proto_test.go deleted file mode 100644 index bbdb066..0000000 --- a/proto_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2017 Ernest Micklei -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package proto - -import ( - "bytes" - "os" - "path/filepath" - "testing" -) - -func TestParseFormattedProto2UnitTest(t *testing.T) { - parseFormattedParsed(t, filepath.Join("cmd", "protofmt", "unittest_proto2.proto")) -} - -func TestParseFormattedProto3UnitTest(t *testing.T) { - parseFormattedParsed(t, filepath.Join("cmd", "protofmt", "unittest_proto3.proto")) -} - -func TestParseFormattedProto3ArenaUnitTest(t *testing.T) { - parseFormattedParsed(t, filepath.Join("cmd", "protofmt", "unittest_proto3_arena.proto")) -} - -func parseFormattedParsed(t *testing.T, filename string) { - // open it - f, err := os.Open(filename) - if err != nil { - t.Fatal(filename, err) - } - defer f.Close() - // parse it - p := NewParser(f) - p.Filename(filename) - def, err := p.Parse() - if err != nil { - t.Fatal(filename, err) - } - // count it - c := new(counter) - c.Count(def.Elements) - beforeCount := c.count - - // format it - out := new(bytes.Buffer) - fmt := NewFormatter(out, " ") - fmt.Format(def) - // parse the formatted content - fp := NewParser(bytes.NewReader(out.Bytes())) - _, err = fp.Parse() - if err != nil { - t.Fatal(filename, err) - } - // count it again - c.count = 0 - c.Count(def.Elements) - afterCount := c.count - if got, want := afterCount, beforeCount; got != want { - t.Errorf("[%s] got [%v] want [%v]", filename, got, want) - } - t.Log("# proto elements", afterCount) -} - -type counter struct { - count int -} - -func (c *counter) Count(elements []Visitee) { - for _, each := range elements { - each.Accept(c) - } -} -func (c *counter) VisitMessage(m *Message) { - c.count++ - c.Count(m.Elements) -} -func (c *counter) VisitService(v *Service) { - c.count++ - c.Count(v.Elements) -} -func (c *counter) VisitSyntax(s *Syntax) { c.count++ } -func (c *counter) VisitPackage(p *Package) { c.count++ } -func (c *counter) VisitOption(o *Option) { c.count++ } -func (c *counter) VisitImport(i *Import) { c.count++ } -func (c *counter) VisitNormalField(i *NormalField) { c.count++ } -func (c *counter) VisitEnumField(i *EnumField) { c.count++ } -func (c *counter) VisitEnum(e *Enum) { - c.count++ - c.Count(e.Elements) -} -func (c *counter) VisitComment(e *Comment) { c.count++ } -func (c *counter) VisitOneof(o *Oneof) { - c.count++ - c.Count(o.Elements) -} -func (c *counter) VisitOneofField(o *OneOfField) { c.count++ } -func (c *counter) VisitReserved(rs *Reserved) { c.count++ } -func (c *counter) VisitRPC(rpc *RPC) { c.count++ } -func (c *counter) VisitMapField(f *MapField) { c.count++ } -func (c *counter) VisitGroup(g *Group) { - c.count++ - c.Count(g.Elements) -} -func (c *counter) VisitExtensions(e *Extensions) { c.count++ } diff --git a/service.go b/service.go index e3496a5..218a27d 100644 --- a/service.go +++ b/service.go @@ -24,8 +24,6 @@ package proto import ( - "bytes" - "io" "text/scanner" ) @@ -133,51 +131,6 @@ func (r *RPC) inlineComment(c *Comment) { r.InlineComment = c } -// columns returns printable source tokens -func (r *RPC) columns() (cols []aligned) { - cols = append(cols, - leftAligned("rpc "), - leftAligned(r.Name), - leftAligned(" (")) - if r.StreamsRequest { - cols = append(cols, leftAligned("stream ")) - } else { - cols = append(cols, alignedEmpty) - } - cols = append(cols, - leftAligned(r.RequestType), - leftAligned(") "), - leftAligned("returns"), - leftAligned(" (")) - if r.StreamsReturns { - cols = append(cols, leftAligned("stream ")) - } else { - cols = append(cols, alignedEmpty) - } - cols = append(cols, - leftAligned(r.ReturnsType), - leftAligned(")")) - if len(r.Options) > 0 { - buf := new(bytes.Buffer) - io.WriteString(buf, " {\n") - f := NewFormatter(buf, " ") // TODO get separator, now 2 spaces - f.level(1) - for _, each := range r.Options { - each.Accept(f) - io.WriteString(buf, "\n") - } - f.indent(-1) - io.WriteString(buf, "}") - cols = append(cols, notAligned(buf.String())) - } else { - cols = append(cols, alignedSemicolon) - } - if r.InlineComment != nil { - cols = append(cols, notAligned(" //"), notAligned(r.InlineComment.Message())) - } - return cols -} - // parse continues after reading "rpc" func (r *RPC) parse(p *Parser) error { pos, tok, lit := p.next() diff --git a/service_test.go b/service_test.go index 4b80997..8836050 100644 --- a/service_test.go +++ b/service_test.go @@ -98,5 +98,4 @@ func TestRPCWithOptionAggregateSyntax(t *testing.T) { if got, want := opt.AggregatedConstants[1].Source, "test2"; got != want { t.Errorf("got [%v] want [%v]", got, want) } - t.Log(formatted(srv)) } diff --git a/visitor.go b/visitor.go index 73c10b8..f1441a1 100644 --- a/visitor.go +++ b/visitor.go @@ -54,35 +54,3 @@ type Visitee interface { type Documented interface { Doc() *Comment } - -// reflector is a Visitor that can tell the short type name of a Visitee. -type reflector struct { - name string -} - -// sole instance of reflector -var namer = new(reflector) - -func (r *reflector) VisitMessage(m *Message) { r.name = "Message" } -func (r *reflector) VisitService(v *Service) { r.name = "Service" } -func (r *reflector) VisitSyntax(s *Syntax) { r.name = "Syntax" } -func (r *reflector) VisitPackage(p *Package) { r.name = "Package" } -func (r *reflector) VisitOption(o *Option) { r.name = "Option" } -func (r *reflector) VisitImport(i *Import) { r.name = "Import" } -func (r *reflector) VisitNormalField(i *NormalField) { r.name = "NormalField" } -func (r *reflector) VisitEnumField(i *EnumField) { r.name = "EnumField" } -func (r *reflector) VisitEnum(e *Enum) { r.name = "Enum" } -func (r *reflector) VisitComment(e *Comment) { r.name = "Comment" } -func (r *reflector) VisitOneof(o *Oneof) { r.name = "Oneof" } -func (r *reflector) VisitOneofField(o *OneOfField) { r.name = "OneOfField" } -func (r *reflector) VisitReserved(rs *Reserved) { r.name = "Reserved" } -func (r *reflector) VisitRPC(rpc *RPC) { r.name = "RPC" } -func (r *reflector) VisitMapField(f *MapField) { r.name = "MapField" } -func (r *reflector) VisitGroup(g *Group) { r.name = "Group" } -func (r *reflector) VisitExtensions(e *Extensions) { r.name = "Extensions" } - -// nameOfVisitee returns the short type name of a Visitee. -func nameOfVisitee(e Visitee) string { - e.Accept(namer) - return namer.name -}