79 Commits

Author SHA1 Message Date
Manfred Touron
7e6c4a9401 Update README.md 2016-12-27 13:58:27 +01:00
Manfred Touron
d6aa9a06cc Merge pull request #35 from moul/dev/moul/gokit-unary-less-service
Go-kit example: support services without unary calls
2016-12-26 16:41:08 +01:00
Manfred Touron
877e93aa7c Go-kit example: support services without unary calls 2016-12-26 16:20:46 +01:00
Manfred Touron
cdb9580565 Merge pull request #33 from moul/dev/vgheri/isRepeated
Adds helper to know if a field is a repeated one. Closes #32
2016-12-26 16:19:34 +01:00
Valerio Gheri
f78470553b Adds helper to know if a field is a repeated one. Closes #32 2016-12-26 12:13:04 +01:00
Manfred Touron
c26d72d1ad Merge pull request #31 from moul/dev/moul/gokit-grpcclient
Add basic go-kit gRPC client
2016-12-25 22:43:58 +01:00
Manfred Touron
91e9114c24 Regenerate boilerplate 2016-12-25 19:55:34 +01:00
Manfred Touron
f5d97d64c7 Add go-kit client 2016-12-25 19:50:30 +01:00
Manfred Touron
4c53f8ebdd Merge pull request #30 from moul/dev/moul/handle-streams
Go-kit example: Handle streams
2016-12-24 11:00:56 +01:00
Manfred Touron
718f9120e4 Handle streams 2016-12-23 19:20:44 +01:00
Manfred Touron
f4f2300417 Merge pull request #29 from proullon/dev/proullon/http
feat (helper): handle google.api.http option with httpVerb and httpPath
2016-12-23 00:06:32 +01:00
Pierre Roullon
c7d0a86fec feat (helper): handle google.api.http option with httpVerb and httpPath 2016-12-22 22:42:32 +00:00
Manfred Touron
453376e811 Merge pull request #28 from proullon/dev/proullon/fix
fix (helper): fix isFieldMessage
2016-12-21 16:05:35 +01:00
Pierre Roullon
49d31f1636 fix (helper): fix isFieldMessage 2016-12-21 14:54:48 +00:00
Manfred Touron
7d8a132834 Merge pull request #27 from moul/fix-travis
Fix travis
2016-12-21 10:50:17 +01:00
Manfred Touron
e8332ed718 Fix travis 2016-12-21 10:48:00 +01:00
Manfred Touron
e4160940c1 Merge pull request #26 from proullon/dev/proullon/messagetype
feat (helper): add field reflection helpers getMessageType and isFieldMessage
2016-12-21 10:45:00 +01:00
Manfred Touron
88a2f47522 Better reliability on generated message names 2016-12-21 10:32:27 +01:00
Pierre Roullon
5dd30f38f3 feat (helper): add field reflection helpers getMessageType and isFieldMessage 2016-12-21 09:26:26 +00:00
Manfred Touron
d0ac6afb18 Bump deps 2016-12-21 10:25:12 +01:00
Manfred Touron
15db6dce00 Add docker helpers in Makefile 2016-12-20 13:36:25 +01:00
Manfred Touron
19ea337fa6 Merge pull request #24 from zoontek/js-example
JS-grpc generation
2016-12-20 11:45:35 +01:00
Mathieu Acthernoene
536162a58b Rewrite simple test (only grpc output) 2016-12-20 11:31:46 +01:00
Mathieu Acthernoene
304fba375b helloworld_js generation complete 2016-12-19 15:43:38 +01:00
Mathieu Acthernoene
5c6941cf87 Replace user example by helloworld example, cleanup 2016-12-19 15:21:28 +01:00
Manfred Touron
2195db0de2 Update README.md 2016-12-17 21:44:04 +01:00
Mathieu Acthernoene
eec84d5d96 Remove hardcoded exports 2016-12-16 16:39:31 +01:00
Mathieu Acthernoene
d38fbfccf0 Remove unsupported imports 2016-12-16 16:24:05 +01:00
Mathieu Acthernoene
abbd30d34c Working js grpc generation (same as official output) 2016-12-16 16:08:37 +01:00
Manfred Touron
5b8c9e93dc Update README.md 2016-12-15 17:49:18 +01:00
Manfred Touron
9cde3288ea Add moul/translator reference 2016-12-15 17:47:14 +01:00
Manfred Touron
d3abcca373 Regenerate go-kit example with new encoder 2016-12-15 16:30:14 +01:00
Manfred Touron
df709b52ac Refactor the go-kit templates to make imports generic 2016-12-15 16:28:04 +01:00
Manfred Touron
f9e191c6a4 Add templateDir variable 2016-12-15 16:25:46 +01:00
Manfred Touron
8e2be0f866 Merge pull request #23 from zoontek/update-readme
Update readme
2016-12-15 13:56:23 +01:00
Manfred Touron
869e37e163 Bump sprig@latest 2016-12-15 13:43:43 +01:00
Mathieu Acthernoene
5489e68995 typo 2016-12-15 13:41:32 +01:00
Mathieu Acthernoene
1bbb1dfb26 Update readme 2016-12-15 13:40:39 +01:00
Manfred Touron
6beb5868e8 Merge pull request #22 from zoontek/replace-funcmap
Replace funcmap
2016-12-15 13:31:47 +01:00
Mathieu Acthernoene
da88fbcbd7 use interfaces instead of strings 2016-12-15 13:31:16 +01:00
Mathieu Acthernoene
add7ae7237 Extract ProtoHelpersFuncMap in its own file 2016-12-15 13:28:57 +01:00
Mathieu Acthernoene
d7c3d1a32b Merge pull request #1 from QuentinPerez/fix-race
🐛 fix race condition on ProtoHelpersFuncMap
2016-12-15 13:18:21 +01:00
Quentin Perez
8b7fa40e87 🐛 fix race condition on ProtoHelpersFuncMap 2016-12-15 12:34:56 +01:00
Mathieu Acthernoene
2ab581a1d6 Add first & last helpers 2016-12-15 12:22:23 +01:00
Mathieu Acthernoene
3b5a2eeafe Add JSON utilities back 2016-12-15 12:14:47 +01:00
Mathieu Acthernoene
e48d798d89 Merge custom Funcmap with sprig 2016-12-15 12:08:00 +01:00
Mathieu Acthernoene
f48fe29ebf Replace funcmap dep with sprig 2016-12-15 12:03:02 +01:00
Manfred Touron
ae44a872b3 Update examp;le 2016-12-15 11:06:42 +01:00
Manfred Touron
7907fb79d9 Expose environment 2016-12-15 11:01:29 +01:00
Manfred Touron
407790640d Expose TemplateDir in the AST 2016-12-15 10:59:48 +01:00
Manfred Touron
14d2af18a7 Merge pull request #21 from QuentinPerez/patch-1
a little contribution
2016-12-15 01:29:38 +01:00
Quentin Perez
ba1f64a731 don't print error when debug=false 2016-12-14 11:08:51 +01:00
Quentin Perez
aa9a474262 generate tmpl in parallel 2016-12-14 11:07:05 +01:00
Quentin Perez
1afdd936da 🔨 rework genAst 2016-12-14 11:06:24 +01:00
Quentin Perez
a4749d98ae ✏️ json tag 2016-12-14 11:04:34 +01:00
Quentin Perez
b4d1f1f9bb remove kr/fs dependency 2016-12-14 10:33:08 +01:00
Guilhem Fanton
2ae75f6702 Add js-grpc template (#20) 2016-12-13 19:10:02 +01:00
Sacha Froment
6c946d62eb Add k8s example (#19) 2016-12-13 19:09:29 +01:00
Manfred Touron
514198f2e5 Add slides (#16)
* Initial version of the slides

* Add usages section

* Add pros & cons

* Add assets/wc.png

* Add screenshot + new elements

* Add new screenshots

* Add examples

* Update image

* Last words

* Last words

* Add slides.pdf
2016-12-13 19:08:37 +01:00
Manfred Touron
ff7e469a05 Merge pull request #18 from moul/dev/moul/cleanup
Remove user.logout method
2016-12-13 17:42:09 +01:00
Manfred Touron
9c249b45a4 Install golang deps 2016-12-13 17:39:02 +01:00
Manfred Touron
b34abe8c12 Install protoc-gen-gogo 2016-12-13 17:37:26 +01:00
Manfred Touron
c83a19d80c Remove user.logout method 2016-12-13 17:32:32 +01:00
Manfred Touron
0336dc5217 Merge pull request #17 from moul/dev/moul/add-user-service
Add user service
2016-12-13 17:21:27 +01:00
Manfred Touron
dbd5ed55a4 make test now tests the go-kit example 2016-12-13 17:21:15 +01:00
Manfred Touron
d252b157c9 Add user-service generated-code 2016-12-13 17:19:04 +01:00
Manfred Touron
605610f7d0 Add user-service 2016-12-13 17:18:55 +01:00
Manfred Touron
8b771ff4c7 Merge pull request #15 from moul/dev/moul/go-kit-example
Go-kit example
2016-12-13 16:15:28 +01:00
Manfred Touron
701c12f866 Move all generated code in the gen sub-directory 2016-12-13 16:11:50 +01:00
Manfred Touron
d748878896 Add entrypoint 2016-12-13 16:03:16 +01:00
Manfred Touron
f62940ac4c Generate endpoints + transports 2016-12-13 15:31:37 +01:00
Manfred Touron
bffc245a82 generate services boilerplate code 2016-12-13 11:05:06 +01:00
Manfred Touron
71fb53ae02 Add templates 2016-12-13 10:59:34 +01:00
Manfred Touron
ce8f7bd8a7 Add Makefile 2016-12-13 10:36:55 +01:00
Manfred Touron
218f25ab56 Add go-kit example proto definitions 2016-12-13 10:27:52 +01:00
Manfred Touron
09a9873bad Merge pull request #14 from moul/dev/moul/add-travis
Setup unit tests (fix #13)
2016-12-12 19:37:03 +01:00
Manfred Touron
664498d53d Setup unit tests (fix #13) 2016-12-12 19:35:59 +01:00
Manfred Touron
1146013b1f Add funcmap description in the README 2016-12-12 17:24:39 +01:00
Manfred Touron
19a3db3d08 bump funcmap@1.1.1 2016-12-01 10:19:09 +01:00
127 changed files with 12865 additions and 996 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
/protoc-gen-gotemplate
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a

14
.travis.yml Normal file
View File

@@ -0,0 +1,14 @@
language: go
go: 1.7.x
install:
- wget https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/.travis/install-protoc.sh && chmod +x install-protoc.sh && ./install-protoc.sh 3.1.0
- go get github.com/gogo/protobuf/protoc-gen-gogo
script:
- make install
- make test
cache:
directories:
- $HOME/local
env:
global:
- "PATH=$PATH:$HOME/local/bin"

View File

@@ -1,5 +1,5 @@
FROM golang:1.7.3
FROM znly/protoc
RUN apk --update add make git go rsync
COPY . /go/src/github.com/moul/protoc-gen-gotemplate
WORKDIR /go/src/github.com/moul/protoc-gen-gotemplate
RUN go install .
ENTRYPOINT ["protoc-gen-gotemplate"]

20
Makefile Normal file
View File

@@ -0,0 +1,20 @@
.PHONY: build
build:
go build -o protoc-gen-gotemplate .
.PHONY: install
install:
go install .
.PHONY: test
test: build
cd examples/dummy && make
cd examples/js-grpc && make
.PHONY: docker.build
docker.build:
docker build --pull -t moul/protoc-gen-gotemplate .
.PHONY: docker.push
docker.push: docker.build
docker push moul/protoc-gen-gotemplate

View File

@@ -1,4 +1,4 @@
# protoc-gen-gotemplate
# `protoc-gen-gotemplate`
:open_file_folder: protocol generator + golang text/template (protobuf)
Generic protocol buffer generator backed by Golang's [text/template](https://golang.org/pkg/text/template).
@@ -13,7 +13,7 @@ The plugin can generate files based on a template directory using the [Golang's
`protoc-gen-gotemplate` requires a **template_dir** directory *(by default `./templates`)*.
Every files ending with `.tmpl` will be processed and written in the destination folder, following the file hierarchy of the `template_dir`, and removing the `.tmpl` extension.
Every files ending with `.tmpl` will be processed and written in the destination folder, following the file hierarchy of the `template_dir`, and removing the `.tmpl` extension.
---
@@ -38,12 +38,32 @@ $> protoc --gotemplate_out=debug=true,template_dir=/path/to/template/directory:.
See [examples](./examples).
## Funcmap
This project uses [Masterminds/sprig](https://github.com/Masterminds/sprig) library and additional functions to extend the builtin [text/template](https://golang.org/pkg/text/template) helpers.
Non-exhaustive list of new helpers:
* **all the functions from [sprig](https://github.com/Masterminds/sprig)**
* `json`
* `prettyjson`
* `first`
* `last`
See the project helpers for the complete list.
## Install
* Install the **Go** compiler and tools from https://golang.org/doc/install
* Install **protobuf**: `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`
* Install **protoc-gen-gotemplate**: `go get -u github.com/moul/protoc-gen-gotemplate`
## Projects using `protoc-gen-gotemplate`
* [kafka-gateway](https://github.com/moul/kafka-gateway/): Kafka gateway/proxy (gRPC + http) using Go-Kit
* [translator](https://github.com/moul/translator): Translator Micro-service using Gettext and Go-Kit
* [acl](https://github.com/moul/acl): ACL micro-service (gRPC/protobuf + http/json)
## License
MIT

View File

@@ -11,36 +11,39 @@ import (
"github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/kr/fs"
"github.com/moul/funcmap"
)
type GenericTemplateBasedEncoder struct {
templateDir string
service *descriptor.ServiceDescriptorProto
file *descriptor.FileDescriptorProto
debug bool
templateDir string
service *descriptor.ServiceDescriptorProto
file *descriptor.FileDescriptorProto
debug bool
destinationDir string
}
type Ast struct {
BuildDate time.Time `json:"build-date"`
BuildHostname string `json:"build-hostname"`
BuildUser string `json:"build-user"`
GoPWD string `json:"go-pwd",omitempty`
PWD string `json:"pwd"`
Debug bool `json:"debug"`
File *descriptor.FileDescriptorProto `json:"file"`
RawFilename string `json:"raw-filename"`
Filename string `json:"filename"`
Service *descriptor.ServiceDescriptorProto `json:"service"`
BuildDate time.Time `json:"build-date"`
BuildHostname string `json:"build-hostname"`
BuildUser string `json:"build-user"`
GoPWD string `json:"go-pwd,omitempty"`
PWD string `json:"pwd"`
Debug bool `json:"debug"`
DestinationDir string `json:"destination-dir"`
File *descriptor.FileDescriptorProto `json:"file"`
RawFilename string `json:"raw-filename"`
Filename string `json:"filename"`
TemplateDir string `json:"template-dir"`
Service *descriptor.ServiceDescriptorProto `json:"service"`
Environment []string `json:"environment"`
}
func NewGenericTemplateBasedEncoder(templateDir string, service *descriptor.ServiceDescriptorProto, file *descriptor.FileDescriptorProto, debug bool) (e *GenericTemplateBasedEncoder) {
func NewGenericTemplateBasedEncoder(templateDir string, service *descriptor.ServiceDescriptorProto, file *descriptor.FileDescriptorProto, debug bool, destinationDir string) (e *GenericTemplateBasedEncoder) {
e = &GenericTemplateBasedEncoder{
service: service,
file: file,
templateDir: templateDir,
debug: debug,
service: service,
file: file,
templateDir: templateDir,
debug: debug,
destinationDir: destinationDir,
}
if debug {
@@ -53,32 +56,27 @@ func NewGenericTemplateBasedEncoder(templateDir string, service *descriptor.Serv
func (e *GenericTemplateBasedEncoder) templates() ([]string, error) {
filenames := []string{}
walker := fs.Walk(e.templateDir)
for walker.Step() {
if err := walker.Err(); err != nil {
return nil, err
}
if walker.Stat().IsDir() {
continue
}
if filepath.Ext(walker.Path()) != ".tmpl" {
continue
}
rel, err := filepath.Rel(e.templateDir, walker.Path())
err := filepath.Walk(e.templateDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil, err
return err
}
if info.IsDir() {
return nil
}
if filepath.Ext(path) != ".tmpl" {
return nil
}
rel, err := filepath.Rel(e.templateDir, path)
if err != nil {
return err
}
if e.debug {
log.Printf("new template: %q", rel)
}
filenames = append(filenames, rel)
}
return filenames, nil
return nil
})
return filenames, err
}
func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, error) {
@@ -93,91 +91,88 @@ func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, err
}
}
ast := Ast{
BuildDate: time.Now(),
BuildHostname: hostname,
BuildUser: os.Getenv("USER"),
PWD: pwd,
GoPWD: goPwd,
File: e.file,
RawFilename: templateFilename,
// Filename: "",
Service: e.service,
BuildDate: time.Now(),
BuildHostname: hostname,
BuildUser: os.Getenv("USER"),
PWD: pwd,
GoPWD: goPwd,
File: e.file,
TemplateDir: e.templateDir,
DestinationDir: e.destinationDir,
RawFilename: templateFilename,
Filename: "",
Environment: os.Environ(),
Service: e.service,
}
buffer := new(bytes.Buffer)
tmpl, err := template.New("").Funcs(ProtoHelpersFuncMap).Parse(templateFilename)
if err != nil {
return nil, err
}
if err := tmpl.Execute(buffer, ast); err != nil {
return nil, err
}
ast.Filename = buffer.String()
return &ast, nil
}
func (e *GenericTemplateBasedEncoder) buildContent(templateFilename string) (string, error) {
func (e *GenericTemplateBasedEncoder) buildContent(templateFilename string) (string, string, error) {
// initialize template engine
fullPath := filepath.Join(e.templateDir, templateFilename)
templateName := filepath.Base(fullPath)
tmpl, err := template.New(templateName).Funcs(funcmap.FuncMap).ParseFiles(fullPath)
tmpl, err := template.New(templateName).Funcs(ProtoHelpersFuncMap).ParseFiles(fullPath)
if err != nil {
return "", err
return "", "", err
}
ast, err := e.genAst(templateFilename)
if err != nil {
return "", err
}
// translate the filename
ast.Filename, err = e.translateString(templateFilename, templateFilename)
if err != nil {
return "", err
return "", "", err
}
// generate the content
buffer := new(bytes.Buffer)
if err := tmpl.Execute(buffer, ast); err != nil {
return "", err
return "", "", err
}
return buffer.String(), nil
}
func (e *GenericTemplateBasedEncoder) translateString(input string, templateFilename string) (string, error) {
buffer := new(bytes.Buffer)
tmpl, err := template.New("").Funcs(funcmap.FuncMap).Parse(input)
if err != nil {
return "", err
}
ast, err := e.genAst(templateFilename)
if err != nil {
return "", err
}
if err := tmpl.Execute(buffer, ast); err != nil {
return "", err
}
return buffer.String(), nil
return buffer.String(), ast.Filename, nil
}
func (e *GenericTemplateBasedEncoder) Files() []*plugin_go.CodeGeneratorResponse_File {
files := []*plugin_go.CodeGeneratorResponse_File{}
templates, err := e.templates()
if err != nil {
log.Fatalf("cannot get templates from %q: %v", e.templateDir, err)
}
length := len(templates)
files := make([]*plugin_go.CodeGeneratorResponse_File, 0, length)
errChan := make(chan error, length)
resultChan := make(chan *plugin_go.CodeGeneratorResponse_File, length)
for _, templateFilename := range templates {
content, err := e.buildContent(templateFilename)
if err != nil {
panic(err)
}
go func(tmpl string) {
content, translatedFilename, err := e.buildContent(tmpl)
if err != nil {
errChan <- err
return
}
filename := translatedFilename[:len(translatedFilename)-len(".tmpl")]
translatedFilename, err := e.translateString(templateFilename, templateFilename)
if err != nil {
panic(err)
}
filename := translatedFilename[0 : len(translatedFilename)-len(".tmpl")]
files = append(files, &plugin_go.CodeGeneratorResponse_File{
Content: &content,
Name: &filename,
})
resultChan <- &plugin_go.CodeGeneratorResponse_File{
Content: &content,
Name: &filename,
}
}(templateFilename)
}
for i := 0; i < length; i++ {
select {
case f := <-resultChan:
files = append(files, f)
case err = <-errChan:
}
}
if err != nil {
panic(err)
}
return files
}

View File

@@ -1,10 +1,11 @@
{
"build-date": "2016-11-09T18:39:15.154031816+01:00",
"build-hostname": "moul-rose.local",
"build-user": "moul",
"go-pwd": "github.com/moul/protoc-gen-gotemplate/examples/dummy",
"pwd": "/Users/moul/go/src/github.com/moul/protoc-gen-gotemplate/examples/dummy",
"build-date": "2016-12-20T11:30:36.474403064+01:00",
"build-hostname": "Zoon-MacBook.local",
"build-user": "zoon",
"go-pwd": "github.com/protoc-gen-gotemplate/examples/dummy",
"pwd": "/Users/zoon/Projects/gopath/src/github.com/protoc-gen-gotemplate/examples/dummy",
"debug": false,
"destination-dir": ".",
"file": {
"name": "dummy.proto",
"package": "dummy",
@@ -822,6 +823,7 @@
},
"raw-filename": "export.json.tmpl",
"filename": "export.json.tmpl",
"template-dir": "templates",
"service": {
"name": "DummyService",
"method": [
@@ -838,5 +840,42 @@
"options": {}
}
]
}
},
"environment": [
"TERM_PROGRAM=iTerm.app",
"ANDROID_HOME=/usr/local/opt/android-sdk",
"TERM=xterm-256color",
"SHELL=/bin/zsh",
"MAKEFLAGS=",
"TMPDIR=/var/folders/sq/wlptrlpn4v52xv7xpsgw0fc80000gn/T/",
"Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.q9vxeee00S/Render",
"TERM_PROGRAM_VERSION=3.0.12",
"TERM_SESSION_ID=w0t0p0:6D29EB08-1B96-41B8-8672-0B035605AEE5",
"ZSH=/Users/zoon/.oh-my-zsh",
"USER=zoon",
"SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.5ZcNGIwTRZ/Listeners",
"__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0",
"MAKELEVEL=2",
"PAGER=less",
"MFLAGS=",
"LSCOLORS=Gxfxcxdxbxegedabagacad",
"PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/zoon/Projects/gopath/bin",
"_=/usr/local/bin/protoc",
"PWD=/Users/zoon/Projects/gopath/src/github.com/protoc-gen-gotemplate/examples/dummy",
"JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home",
"EDITOR=micro",
"LANG=en_US.UTF-8",
"ANDROID_SDK=/usr/local/opt/android-sdk",
"ITERM_PROFILE=Default",
"XPC_FLAGS=0x0",
"XPC_SERVICE_NAME=0",
"COLORFGBG=15;0",
"SHLVL=3",
"HOME=/Users/zoon",
"ITERM_SESSION_ID=w0t0p0:6D29EB08-1B96-41B8-8672-0B035605AEE5",
"LESS=-R",
"LOGNAME=zoon",
"LC_CTYPE=UTF-8",
"GOPATH=/Users/zoon/Projects/gopath"
]
}

1
examples/go-kit/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/server

23
examples/go-kit/Makefile Normal file
View File

@@ -0,0 +1,23 @@
SOURCES := $(shell find . -name "*.proto" -not -path ./vendor/\*)
TARGETS_GO := $(foreach source, $(SOURCES), $(source)_go)
TARGETS_TMPL := $(foreach source, $(SOURCES), $(source)_tmpl)
service_name = $(word 2,$(subst /, ,$1))
.PHONY: build
build: server
server: $(TARGETS_GO) $(TARGETS_TMPL)
go build -o server .
$(TARGETS_GO): %_go:
protoc --gogo_out=plugins=grpc:. "$*"
@mkdir -p services/$(call service_name,$*)/gen/pb
@mv ./services/$(call service_name,$*)/$(call service_name,$*).pb.go ./services/$(call service_name,$*)/gen/pb/pb.go
$(TARGETS_TMPL): %_tmpl:
@mkdir -p $(dir $*)gen
protoc -I. --gotemplate_out=destination_dir=services/$(call service_name,$*)/gen,template_dir=templates:services "$*"
@rm -rf services/services # need to investigate why this directory is created
gofmt -w $(dir $*)gen

95
examples/go-kit/main.go Normal file
View File

@@ -0,0 +1,95 @@
package main
import (
"context"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/go-kit/kit/log"
"github.com/gorilla/handlers"
"google.golang.org/grpc"
session_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session"
session_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
session_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
session_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/grpc"
session_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/http"
sprint_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint"
sprint_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
sprint_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
sprint_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/grpc"
sprint_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/http"
user_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user"
user_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
user_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
user_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/grpc"
user_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/http"
)
func main() {
mux := http.NewServeMux()
ctx := context.Background()
errc := make(chan error)
s := grpc.NewServer()
var logger log.Logger
{
logger = log.NewLogfmtLogger(os.Stdout)
logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
logger = log.NewContext(logger).With("caller", log.DefaultCaller)
}
// initialize services
{
svc := session_svc.New()
endpoints := session_endpoints.MakeEndpoints(svc)
srv := session_grpctransport.MakeGRPCServer(ctx, endpoints)
session_pb.RegisterSessionServiceServer(s, srv)
session_httptransport.RegisterHandlers(ctx, svc, mux, endpoints)
}
{
svc := sprint_svc.New()
endpoints := sprint_endpoints.MakeEndpoints(svc)
srv := sprint_grpctransport.MakeGRPCServer(ctx, endpoints)
sprint_pb.RegisterSprintServiceServer(s, srv)
sprint_httptransport.RegisterHandlers(ctx, svc, mux, endpoints)
}
{
svc := user_svc.New()
endpoints := user_endpoints.MakeEndpoints(svc)
srv := user_grpctransport.MakeGRPCServer(ctx, endpoints)
user_pb.RegisterUserServiceServer(s, srv)
user_httptransport.RegisterHandlers(ctx, svc, mux, endpoints)
}
// start servers
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
errc <- fmt.Errorf("%s", <-c)
}()
go func() {
logger := log.NewContext(logger).With("transport", "HTTP")
logger.Log("addr", ":8000")
errc <- http.ListenAndServe(":8000", handlers.LoggingHandler(os.Stderr, mux))
}()
go func() {
logger := log.NewContext(logger).With("transport", "gRPC")
ln, err := net.Listen("tcp", ":9000")
if err != nil {
errc <- err
return
}
logger.Log("addr", ":9000")
errc <- s.Serve(ln)
}()
logger.Log("exit", <-errc)
}

View File

@@ -0,0 +1,44 @@
package session_clientgrpc
import (
jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
)
func New(conn *grpc.ClientConn, logger log.Logger) pb.SessionServiceServer {
var loginEndpoint endpoint.Endpoint
{
loginEndpoint = grpctransport.NewClient(
conn,
"session.SessionService",
"Login",
EncodeLoginRequest,
DecodeLoginResponse,
pb.LoginResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
return &endpoints.Endpoints{
LoginEndpoint: loginEndpoint,
}
}
func EncodeLoginRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.LoginRequest)
return req, nil
}
func DecodeLoginResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.LoginResponse)
return response, nil
}

View File

@@ -0,0 +1,43 @@
package session_endpoints
import (
"fmt"
"github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
context "golang.org/x/net/context"
)
var _ = fmt.Errorf
type StreamEndpoint func(server interface{}, req interface{}) (err error)
type Endpoints struct {
LoginEndpoint endpoint.Endpoint
}
func (e *Endpoints) Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) {
out, err := e.LoginEndpoint(ctx, in)
if err != nil {
return &pb.LoginResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.LoginResponse), err
}
func MakeLoginEndpoint(svc pb.SessionServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.LoginRequest)
rep, err := svc.Login(ctx, req)
if err != nil {
return &pb.LoginResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeEndpoints(svc pb.SessionServiceServer) Endpoints {
return Endpoints{
LoginEndpoint: MakeLoginEndpoint(svc),
}
}

View File

@@ -0,0 +1,178 @@
// Code generated by protoc-gen-gogo.
// source: services/session/session.proto
// DO NOT EDIT!
/*
Package session is a generated protocol buffer package.
It is generated from these files:
services/session/session.proto
It has these top-level messages:
LoginRequest
LoginResponse
*/
package session
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type LoginRequest struct {
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
}
func (m *LoginRequest) Reset() { *m = LoginRequest{} }
func (m *LoginRequest) String() string { return proto.CompactTextString(m) }
func (*LoginRequest) ProtoMessage() {}
func (*LoginRequest) Descriptor() ([]byte, []int) { return fileDescriptorSession, []int{0} }
func (m *LoginRequest) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *LoginRequest) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
type LoginResponse struct {
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *LoginResponse) Reset() { *m = LoginResponse{} }
func (m *LoginResponse) String() string { return proto.CompactTextString(m) }
func (*LoginResponse) ProtoMessage() {}
func (*LoginResponse) Descriptor() ([]byte, []int) { return fileDescriptorSession, []int{1} }
func (m *LoginResponse) GetToken() string {
if m != nil {
return m.Token
}
return ""
}
func (m *LoginResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
func init() {
proto.RegisterType((*LoginRequest)(nil), "session.LoginRequest")
proto.RegisterType((*LoginResponse)(nil), "session.LoginResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for SessionService service
type SessionServiceClient interface {
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
}
type sessionServiceClient struct {
cc *grpc.ClientConn
}
func NewSessionServiceClient(cc *grpc.ClientConn) SessionServiceClient {
return &sessionServiceClient{cc}
}
func (c *sessionServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) {
out := new(LoginResponse)
err := grpc.Invoke(ctx, "/session.SessionService/Login", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for SessionService service
type SessionServiceServer interface {
Login(context.Context, *LoginRequest) (*LoginResponse, error)
}
func RegisterSessionServiceServer(s *grpc.Server, srv SessionServiceServer) {
s.RegisterService(&_SessionService_serviceDesc, srv)
}
func _SessionService_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LoginRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SessionServiceServer).Login(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/session.SessionService/Login",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SessionServiceServer).Login(ctx, req.(*LoginRequest))
}
return interceptor(ctx, in, info, handler)
}
var _SessionService_serviceDesc = grpc.ServiceDesc{
ServiceName: "session.SessionService",
HandlerType: (*SessionServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Login",
Handler: _SessionService_Login_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "services/session/session.proto",
}
func init() { proto.RegisterFile("services/session/session.proto", fileDescriptorSession) }
var fileDescriptorSession = []byte{
// 188 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x2b, 0x4e, 0x2d, 0x2a,
0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x4e, 0x2d, 0x2e, 0xce, 0xcc, 0xcf, 0x83, 0xd1, 0x7a, 0x05,
0x45, 0xf9, 0x25, 0xf9, 0x42, 0xec, 0x50, 0xae, 0x92, 0x1b, 0x17, 0x8f, 0x4f, 0x7e, 0x7a, 0x66,
0x5e, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x90, 0x14, 0x17, 0x47, 0x69, 0x71, 0x6a, 0x51,
0x5e, 0x62, 0x6e, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x9c, 0x0f, 0x92, 0x2b, 0x48,
0x2c, 0x2e, 0x2e, 0xcf, 0x2f, 0x4a, 0x91, 0x60, 0x82, 0xc8, 0xc1, 0xf8, 0x4a, 0x76, 0x5c, 0xbc,
0x50, 0x73, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0x44, 0xb8, 0x58, 0x4b, 0xf2, 0xb3, 0x53,
0xf3, 0xa0, 0xa6, 0x40, 0x38, 0x42, 0xe2, 0x5c, 0xec, 0xa9, 0x45, 0x45, 0xf1, 0xb9, 0xc5, 0xe9,
0x50, 0x13, 0xd8, 0x52, 0x8b, 0x8a, 0x7c, 0x8b, 0xd3, 0x8d, 0xbc, 0xb8, 0xf8, 0x82, 0x21, 0x4e,
0x0a, 0x86, 0xb8, 0x5c, 0xc8, 0x82, 0x8b, 0x15, 0x6c, 0xa2, 0x90, 0xa8, 0x1e, 0xcc, 0xed, 0xc8,
0x2e, 0x95, 0x12, 0x43, 0x17, 0x86, 0x58, 0xac, 0xc4, 0x90, 0xc4, 0x06, 0xf6, 0xa3, 0x31, 0x20,
0x00, 0x00, 0xff, 0xff, 0x29, 0x3f, 0x91, 0xc7, 0x05, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,64 @@
package session_grpctransport
import (
"fmt"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
)
// avoid import errors
var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.SessionServiceServer {
options := []grpctransport.ServerOption{}
return &grpcServer{
login: grpctransport.NewServer(
ctx,
endpoints.LoginEndpoint,
decodeRequest,
encodeLoginResponse,
options...,
),
}
}
type grpcServer struct {
login grpctransport.Handler
}
func (s *grpcServer) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
_, rep, err := s.login.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.LoginResponse), nil
}
func encodeLoginResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.LoginResponse)
return resp, nil
}
func decodeRequest(ctx context.Context, grpcReq interface{}) (interface{}, error) {
return grpcReq, nil
}
type streamHandler interface {
Do(server interface{}, req interface{}) (err error)
}
type server struct {
e endpoints.StreamEndpoint
}
func (s server) Do(server interface{}, req interface{}) (err error) {
if err := s.e(server, req); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,43 @@
package session_httptransport
import (
"encoding/json"
context "golang.org/x/net/context"
"log"
"net/http"
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
)
func MakeLoginHandler(ctx context.Context, svc pb.SessionServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeLoginRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeLoginRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.LoginRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func RegisterHandlers(ctx context.Context, svc pb.SessionServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/Login\" (service=Session)")
mux.Handle("/Login", MakeLoginHandler(ctx, svc, endpoints.LoginEndpoint))
return nil
}

View File

@@ -0,0 +1,19 @@
package sessionsvc
import (
"fmt"
"golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
)
type Service struct{}
func New() pb.SessionServiceServer {
return &Service{}
}
func (svc *Service) Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) {
return nil, fmt.Errorf("not implemented")
}

View File

@@ -0,0 +1,17 @@
syntax = "proto3";
package session;
service SessionService {
rpc Login(LoginRequest) returns (LoginResponse) {}
}
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
string token = 1;
string err_msg = 2;
}

View File

@@ -0,0 +1,94 @@
package sprint_clientgrpc
import (
jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
)
func New(conn *grpc.ClientConn, logger log.Logger) pb.SprintServiceServer {
var addsprintEndpoint endpoint.Endpoint
{
addsprintEndpoint = grpctransport.NewClient(
conn,
"sprint.SprintService",
"AddSprint",
EncodeAddSprintRequest,
DecodeAddSprintResponse,
pb.AddSprintResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
var closesprintEndpoint endpoint.Endpoint
{
closesprintEndpoint = grpctransport.NewClient(
conn,
"sprint.SprintService",
"CloseSprint",
EncodeCloseSprintRequest,
DecodeCloseSprintResponse,
pb.CloseSprintResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
var getsprintEndpoint endpoint.Endpoint
{
getsprintEndpoint = grpctransport.NewClient(
conn,
"sprint.SprintService",
"GetSprint",
EncodeGetSprintRequest,
DecodeGetSprintResponse,
pb.GetSprintResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
return &endpoints.Endpoints{
AddSprintEndpoint: addsprintEndpoint,
CloseSprintEndpoint: closesprintEndpoint,
GetSprintEndpoint: getsprintEndpoint,
}
}
func EncodeAddSprintRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.AddSprintRequest)
return req, nil
}
func DecodeAddSprintResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.AddSprintResponse)
return response, nil
}
func EncodeCloseSprintRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.CloseSprintRequest)
return req, nil
}
func DecodeCloseSprintResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.CloseSprintResponse)
return response, nil
}
func EncodeGetSprintRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.GetSprintRequest)
return req, nil
}
func DecodeGetSprintResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.GetSprintResponse)
return response, nil
}

View File

@@ -0,0 +1,89 @@
package sprint_endpoints
import (
"fmt"
"github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
context "golang.org/x/net/context"
)
var _ = fmt.Errorf
type StreamEndpoint func(server interface{}, req interface{}) (err error)
type Endpoints struct {
AddSprintEndpoint endpoint.Endpoint
CloseSprintEndpoint endpoint.Endpoint
GetSprintEndpoint endpoint.Endpoint
}
func (e *Endpoints) AddSprint(ctx context.Context, in *pb.AddSprintRequest) (*pb.AddSprintResponse, error) {
out, err := e.AddSprintEndpoint(ctx, in)
if err != nil {
return &pb.AddSprintResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.AddSprintResponse), err
}
func (e *Endpoints) CloseSprint(ctx context.Context, in *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) {
out, err := e.CloseSprintEndpoint(ctx, in)
if err != nil {
return &pb.CloseSprintResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.CloseSprintResponse), err
}
func (e *Endpoints) GetSprint(ctx context.Context, in *pb.GetSprintRequest) (*pb.GetSprintResponse, error) {
out, err := e.GetSprintEndpoint(ctx, in)
if err != nil {
return &pb.GetSprintResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.GetSprintResponse), err
}
func MakeAddSprintEndpoint(svc pb.SprintServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.AddSprintRequest)
rep, err := svc.AddSprint(ctx, req)
if err != nil {
return &pb.AddSprintResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeCloseSprintEndpoint(svc pb.SprintServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.CloseSprintRequest)
rep, err := svc.CloseSprint(ctx, req)
if err != nil {
return &pb.CloseSprintResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeGetSprintEndpoint(svc pb.SprintServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.GetSprintRequest)
rep, err := svc.GetSprint(ctx, req)
if err != nil {
return &pb.GetSprintResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeEndpoints(svc pb.SprintServiceServer) Endpoints {
return Endpoints{
AddSprintEndpoint: MakeAddSprintEndpoint(svc),
CloseSprintEndpoint: MakeCloseSprintEndpoint(svc),
GetSprintEndpoint: MakeGetSprintEndpoint(svc),
}
}

View File

@@ -0,0 +1,357 @@
// Code generated by protoc-gen-gogo.
// source: services/sprint/sprint.proto
// DO NOT EDIT!
/*
Package sprint is a generated protocol buffer package.
It is generated from these files:
services/sprint/sprint.proto
It has these top-level messages:
AddSprintRequest
AddSprintResponse
CloseSprintRequest
CloseSprintResponse
GetSprintRequest
GetSprintResponse
Sprint
*/
package sprint
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type AddSprintRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *AddSprintRequest) Reset() { *m = AddSprintRequest{} }
func (m *AddSprintRequest) String() string { return proto.CompactTextString(m) }
func (*AddSprintRequest) ProtoMessage() {}
func (*AddSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{0} }
func (m *AddSprintRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type AddSprintResponse struct {
Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *AddSprintResponse) Reset() { *m = AddSprintResponse{} }
func (m *AddSprintResponse) String() string { return proto.CompactTextString(m) }
func (*AddSprintResponse) ProtoMessage() {}
func (*AddSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{1} }
func (m *AddSprintResponse) GetSprint() *Sprint {
if m != nil {
return m.Sprint
}
return nil
}
func (m *AddSprintResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
type CloseSprintRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (m *CloseSprintRequest) Reset() { *m = CloseSprintRequest{} }
func (m *CloseSprintRequest) String() string { return proto.CompactTextString(m) }
func (*CloseSprintRequest) ProtoMessage() {}
func (*CloseSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{2} }
func (m *CloseSprintRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type CloseSprintResponse struct {
ErrMsg string `protobuf:"bytes,1,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *CloseSprintResponse) Reset() { *m = CloseSprintResponse{} }
func (m *CloseSprintResponse) String() string { return proto.CompactTextString(m) }
func (*CloseSprintResponse) ProtoMessage() {}
func (*CloseSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{3} }
func (m *CloseSprintResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
type GetSprintRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (m *GetSprintRequest) Reset() { *m = GetSprintRequest{} }
func (m *GetSprintRequest) String() string { return proto.CompactTextString(m) }
func (*GetSprintRequest) ProtoMessage() {}
func (*GetSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{4} }
func (m *GetSprintRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type GetSprintResponse struct {
Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *GetSprintResponse) Reset() { *m = GetSprintResponse{} }
func (m *GetSprintResponse) String() string { return proto.CompactTextString(m) }
func (*GetSprintResponse) ProtoMessage() {}
func (*GetSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{5} }
func (m *GetSprintResponse) GetSprint() *Sprint {
if m != nil {
return m.Sprint
}
return nil
}
func (m *GetSprintResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
type Sprint struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt uint32 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *Sprint) Reset() { *m = Sprint{} }
func (m *Sprint) String() string { return proto.CompactTextString(m) }
func (*Sprint) ProtoMessage() {}
func (*Sprint) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{6} }
func (m *Sprint) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Sprint) GetCreatedAt() uint32 {
if m != nil {
return m.CreatedAt
}
return 0
}
func (m *Sprint) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func init() {
proto.RegisterType((*AddSprintRequest)(nil), "sprint.AddSprintRequest")
proto.RegisterType((*AddSprintResponse)(nil), "sprint.AddSprintResponse")
proto.RegisterType((*CloseSprintRequest)(nil), "sprint.CloseSprintRequest")
proto.RegisterType((*CloseSprintResponse)(nil), "sprint.CloseSprintResponse")
proto.RegisterType((*GetSprintRequest)(nil), "sprint.GetSprintRequest")
proto.RegisterType((*GetSprintResponse)(nil), "sprint.GetSprintResponse")
proto.RegisterType((*Sprint)(nil), "sprint.Sprint")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for SprintService service
type SprintServiceClient interface {
AddSprint(ctx context.Context, in *AddSprintRequest, opts ...grpc.CallOption) (*AddSprintResponse, error)
CloseSprint(ctx context.Context, in *CloseSprintRequest, opts ...grpc.CallOption) (*CloseSprintResponse, error)
GetSprint(ctx context.Context, in *GetSprintRequest, opts ...grpc.CallOption) (*GetSprintResponse, error)
}
type sprintServiceClient struct {
cc *grpc.ClientConn
}
func NewSprintServiceClient(cc *grpc.ClientConn) SprintServiceClient {
return &sprintServiceClient{cc}
}
func (c *sprintServiceClient) AddSprint(ctx context.Context, in *AddSprintRequest, opts ...grpc.CallOption) (*AddSprintResponse, error) {
out := new(AddSprintResponse)
err := grpc.Invoke(ctx, "/sprint.SprintService/AddSprint", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sprintServiceClient) CloseSprint(ctx context.Context, in *CloseSprintRequest, opts ...grpc.CallOption) (*CloseSprintResponse, error) {
out := new(CloseSprintResponse)
err := grpc.Invoke(ctx, "/sprint.SprintService/CloseSprint", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sprintServiceClient) GetSprint(ctx context.Context, in *GetSprintRequest, opts ...grpc.CallOption) (*GetSprintResponse, error) {
out := new(GetSprintResponse)
err := grpc.Invoke(ctx, "/sprint.SprintService/GetSprint", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for SprintService service
type SprintServiceServer interface {
AddSprint(context.Context, *AddSprintRequest) (*AddSprintResponse, error)
CloseSprint(context.Context, *CloseSprintRequest) (*CloseSprintResponse, error)
GetSprint(context.Context, *GetSprintRequest) (*GetSprintResponse, error)
}
func RegisterSprintServiceServer(s *grpc.Server, srv SprintServiceServer) {
s.RegisterService(&_SprintService_serviceDesc, srv)
}
func _SprintService_AddSprint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddSprintRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SprintServiceServer).AddSprint(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/sprint.SprintService/AddSprint",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SprintServiceServer).AddSprint(ctx, req.(*AddSprintRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SprintService_CloseSprint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseSprintRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SprintServiceServer).CloseSprint(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/sprint.SprintService/CloseSprint",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SprintServiceServer).CloseSprint(ctx, req.(*CloseSprintRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SprintService_GetSprint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetSprintRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SprintServiceServer).GetSprint(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/sprint.SprintService/GetSprint",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SprintServiceServer).GetSprint(ctx, req.(*GetSprintRequest))
}
return interceptor(ctx, in, info, handler)
}
var _SprintService_serviceDesc = grpc.ServiceDesc{
ServiceName: "sprint.SprintService",
HandlerType: (*SprintServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AddSprint",
Handler: _SprintService_AddSprint_Handler,
},
{
MethodName: "CloseSprint",
Handler: _SprintService_CloseSprint_Handler,
},
{
MethodName: "GetSprint",
Handler: _SprintService_GetSprint_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "services/sprint/sprint.proto",
}
func init() { proto.RegisterFile("services/sprint/sprint.proto", fileDescriptorSprint) }
var fileDescriptorSprint = []byte{
// 290 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x52, 0x4d, 0x4b, 0xc3, 0x40,
0x10, 0x6d, 0xaa, 0x44, 0x32, 0xa5, 0xa5, 0x1d, 0x0f, 0xc6, 0xa8, 0x20, 0x8b, 0x14, 0x4f, 0x11,
0xea, 0x2f, 0x68, 0x3d, 0x28, 0x88, 0x97, 0xb4, 0xf7, 0x12, 0xbb, 0x43, 0x09, 0xd8, 0x24, 0xee,
0xac, 0xfe, 0x5f, 0xff, 0x89, 0xb0, 0xbb, 0xcd, 0x57, 0x8b, 0x27, 0x4f, 0xc9, 0xec, 0xbc, 0x7d,
0x6f, 0xe6, 0xbd, 0x85, 0x6b, 0x26, 0xf5, 0x9d, 0x6d, 0x88, 0x1f, 0xb8, 0x54, 0x59, 0xae, 0xdd,
0x27, 0x2e, 0x55, 0xa1, 0x0b, 0xf4, 0x6d, 0x25, 0xa6, 0x30, 0x9e, 0x4b, 0xb9, 0x34, 0x45, 0x42,
0x9f, 0x5f, 0xc4, 0x1a, 0x11, 0x4e, 0xf3, 0x74, 0x47, 0xa1, 0x77, 0xeb, 0xdd, 0x07, 0x89, 0xf9,
0x17, 0x2b, 0x98, 0x34, 0x70, 0x5c, 0x16, 0x39, 0x13, 0x4e, 0xc1, 0xd1, 0x18, 0xe8, 0x60, 0x36,
0x8a, 0x9d, 0x86, 0xc3, 0xb9, 0x2e, 0x5e, 0xc0, 0x19, 0x29, 0xb5, 0xde, 0xf1, 0x36, 0xec, 0x1b,
0x4e, 0x9f, 0x94, 0x7a, 0xe3, 0xad, 0xb8, 0x03, 0x7c, 0xfa, 0x28, 0x98, 0xda, 0xfa, 0x23, 0xe8,
0x67, 0xd2, 0xa9, 0xf7, 0x33, 0x29, 0x62, 0x38, 0x6f, 0xa1, 0x9c, 0x7a, 0x83, 0xd5, 0x6b, 0xb1,
0x0a, 0x18, 0x3f, 0x93, 0xfe, 0x9b, 0x73, 0x05, 0x93, 0x06, 0xe6, 0xbf, 0xf6, 0x79, 0x05, 0xdf,
0x42, 0xbb, 0x7a, 0x78, 0x03, 0xb0, 0x51, 0x94, 0x6a, 0x92, 0xeb, 0x54, 0x9b, 0x5b, 0xc3, 0x24,
0x70, 0x27, 0xf3, 0xda, 0xf2, 0x93, 0xda, 0xf2, 0xd9, 0x8f, 0x07, 0x43, 0xcb, 0xb6, 0xb4, 0x49,
0xe2, 0x02, 0x82, 0x2a, 0x04, 0x0c, 0xf7, 0xc3, 0x75, 0xf3, 0x8b, 0x2e, 0x8f, 0x74, 0xec, 0x86,
0xa2, 0x87, 0x2f, 0x30, 0x68, 0x98, 0x89, 0xd1, 0x1e, 0x7b, 0x98, 0x43, 0x74, 0x75, 0xb4, 0x57,
0x31, 0x2d, 0x20, 0xa8, 0x2c, 0xac, 0xa7, 0xe9, 0x3a, 0x5f, 0x4f, 0x73, 0xe0, 0xb7, 0xe8, 0xbd,
0xfb, 0xe6, 0x35, 0x3e, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x9e, 0xb2, 0x1e, 0xad, 0x02,
0x00, 0x00,
}

View File

@@ -0,0 +1,110 @@
package sprint_grpctransport
import (
"fmt"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
)
// avoid import errors
var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.SprintServiceServer {
options := []grpctransport.ServerOption{}
return &grpcServer{
addsprint: grpctransport.NewServer(
ctx,
endpoints.AddSprintEndpoint,
decodeRequest,
encodeAddSprintResponse,
options...,
),
closesprint: grpctransport.NewServer(
ctx,
endpoints.CloseSprintEndpoint,
decodeRequest,
encodeCloseSprintResponse,
options...,
),
getsprint: grpctransport.NewServer(
ctx,
endpoints.GetSprintEndpoint,
decodeRequest,
encodeGetSprintResponse,
options...,
),
}
}
type grpcServer struct {
addsprint grpctransport.Handler
closesprint grpctransport.Handler
getsprint grpctransport.Handler
}
func (s *grpcServer) AddSprint(ctx context.Context, req *pb.AddSprintRequest) (*pb.AddSprintResponse, error) {
_, rep, err := s.addsprint.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.AddSprintResponse), nil
}
func encodeAddSprintResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.AddSprintResponse)
return resp, nil
}
func (s *grpcServer) CloseSprint(ctx context.Context, req *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) {
_, rep, err := s.closesprint.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.CloseSprintResponse), nil
}
func encodeCloseSprintResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.CloseSprintResponse)
return resp, nil
}
func (s *grpcServer) GetSprint(ctx context.Context, req *pb.GetSprintRequest) (*pb.GetSprintResponse, error) {
_, rep, err := s.getsprint.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.GetSprintResponse), nil
}
func encodeGetSprintResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.GetSprintResponse)
return resp, nil
}
func decodeRequest(ctx context.Context, grpcReq interface{}) (interface{}, error) {
return grpcReq, nil
}
type streamHandler interface {
Do(server interface{}, req interface{}) (err error)
}
type server struct {
e endpoints.StreamEndpoint
}
func (s server) Do(server interface{}, req interface{}) (err error) {
if err := s.e(server, req); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,85 @@
package sprint_httptransport
import (
"encoding/json"
context "golang.org/x/net/context"
"log"
"net/http"
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
)
func MakeAddSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeAddSprintRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeAddSprintRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.AddSprintRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func MakeCloseSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeCloseSprintRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeCloseSprintRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.CloseSprintRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func MakeGetSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeGetSprintRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeGetSprintRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.GetSprintRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func RegisterHandlers(ctx context.Context, svc pb.SprintServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/AddSprint\" (service=Sprint)")
mux.Handle("/AddSprint", MakeAddSprintHandler(ctx, svc, endpoints.AddSprintEndpoint))
log.Println("new HTTP endpoint: \"/CloseSprint\" (service=Sprint)")
mux.Handle("/CloseSprint", MakeCloseSprintHandler(ctx, svc, endpoints.CloseSprintEndpoint))
log.Println("new HTTP endpoint: \"/GetSprint\" (service=Sprint)")
mux.Handle("/GetSprint", MakeGetSprintHandler(ctx, svc, endpoints.GetSprintEndpoint))
return nil
}

View File

@@ -0,0 +1,27 @@
package sprintsvc
import (
"fmt"
"golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
)
type Service struct{}
func New() pb.SprintServiceServer {
return &Service{}
}
func (svc *Service) AddSprint(ctx context.Context, in *pb.AddSprintRequest) (*pb.AddSprintResponse, error) {
return nil, fmt.Errorf("not implemented")
}
func (svc *Service) CloseSprint(ctx context.Context, in *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) {
return nil, fmt.Errorf("not implemented")
}
func (svc *Service) GetSprint(ctx context.Context, in *pb.GetSprintRequest) (*pb.GetSprintResponse, error) {
return nil, fmt.Errorf("not implemented")
}

View File

@@ -0,0 +1,38 @@
syntax = "proto3";
package sprint;
service SprintService {
rpc AddSprint(AddSprintRequest) returns (AddSprintResponse) {}
rpc CloseSprint(CloseSprintRequest) returns (CloseSprintResponse) {}
rpc GetSprint(GetSprintRequest) returns (GetSprintResponse) {}
}
message AddSprintRequest {
string name = 1;
}
message AddSprintResponse {
Sprint sprint = 1;
string err_msg = 2;
}
message CloseSprintRequest {
string id = 1;
}
message CloseSprintResponse {
string err_msg = 1;
}
message GetSprintRequest {
string id = 1;
}
message GetSprintResponse {
Sprint sprint = 1;
string err_msg = 2;
}
message Sprint {
string id = 1;
uint32 created_at = 2;
string name = 3;
}

View File

@@ -0,0 +1,69 @@
package user_clientgrpc
import (
jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
)
func New(conn *grpc.ClientConn, logger log.Logger) pb.UserServiceServer {
var createuserEndpoint endpoint.Endpoint
{
createuserEndpoint = grpctransport.NewClient(
conn,
"user.UserService",
"CreateUser",
EncodeCreateUserRequest,
DecodeCreateUserResponse,
pb.CreateUserResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
var getuserEndpoint endpoint.Endpoint
{
getuserEndpoint = grpctransport.NewClient(
conn,
"user.UserService",
"GetUser",
EncodeGetUserRequest,
DecodeGetUserResponse,
pb.GetUserResponse{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
return &endpoints.Endpoints{
CreateUserEndpoint: createuserEndpoint,
GetUserEndpoint: getuserEndpoint,
}
}
func EncodeCreateUserRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.CreateUserRequest)
return req, nil
}
func DecodeCreateUserResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.CreateUserResponse)
return response, nil
}
func EncodeGetUserRequest(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.GetUserRequest)
return req, nil
}
func DecodeGetUserResponse(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.GetUserResponse)
return response, nil
}

View File

@@ -0,0 +1,66 @@
package user_endpoints
import (
"fmt"
"github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
context "golang.org/x/net/context"
)
var _ = fmt.Errorf
type StreamEndpoint func(server interface{}, req interface{}) (err error)
type Endpoints struct {
CreateUserEndpoint endpoint.Endpoint
GetUserEndpoint endpoint.Endpoint
}
func (e *Endpoints) CreateUser(ctx context.Context, in *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
out, err := e.CreateUserEndpoint(ctx, in)
if err != nil {
return &pb.CreateUserResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.CreateUserResponse), err
}
func (e *Endpoints) GetUser(ctx context.Context, in *pb.GetUserRequest) (*pb.GetUserResponse, error) {
out, err := e.GetUserEndpoint(ctx, in)
if err != nil {
return &pb.GetUserResponse{ErrMsg: err.Error()}, err
}
return out.(*pb.GetUserResponse), err
}
func MakeCreateUserEndpoint(svc pb.UserServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.CreateUserRequest)
rep, err := svc.CreateUser(ctx, req)
if err != nil {
return &pb.CreateUserResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeGetUserEndpoint(svc pb.UserServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.GetUserRequest)
rep, err := svc.GetUser(ctx, req)
if err != nil {
return &pb.GetUserResponse{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
func MakeEndpoints(svc pb.UserServiceServer) Endpoints {
return Endpoints{
CreateUserEndpoint: MakeCreateUserEndpoint(svc),
GetUserEndpoint: MakeGetUserEndpoint(svc),
}
}

View File

@@ -0,0 +1,276 @@
// Code generated by protoc-gen-gogo.
// source: services/user/user.proto
// DO NOT EDIT!
/*
Package user is a generated protocol buffer package.
It is generated from these files:
services/user/user.proto
It has these top-level messages:
CreateUserRequest
CreateUserResponse
GetUserRequest
GetUserResponse
User
*/
package user
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type CreateUserRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *CreateUserRequest) Reset() { *m = CreateUserRequest{} }
func (m *CreateUserRequest) String() string { return proto.CompactTextString(m) }
func (*CreateUserRequest) ProtoMessage() {}
func (*CreateUserRequest) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{0} }
func (m *CreateUserRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type CreateUserResponse struct {
User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *CreateUserResponse) Reset() { *m = CreateUserResponse{} }
func (m *CreateUserResponse) String() string { return proto.CompactTextString(m) }
func (*CreateUserResponse) ProtoMessage() {}
func (*CreateUserResponse) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{1} }
func (m *CreateUserResponse) GetUser() *User {
if m != nil {
return m.User
}
return nil
}
func (m *CreateUserResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
type GetUserRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
func (*GetUserRequest) ProtoMessage() {}
func (*GetUserRequest) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{2} }
func (m *GetUserRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type GetUserResponse struct {
User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
}
func (m *GetUserResponse) Reset() { *m = GetUserResponse{} }
func (m *GetUserResponse) String() string { return proto.CompactTextString(m) }
func (*GetUserResponse) ProtoMessage() {}
func (*GetUserResponse) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{3} }
func (m *GetUserResponse) GetUser() *User {
if m != nil {
return m.User
}
return nil
}
func (m *GetUserResponse) GetErrMsg() string {
if m != nil {
return m.ErrMsg
}
return ""
}
type User struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
}
func (m *User) Reset() { *m = User{} }
func (m *User) String() string { return proto.CompactTextString(m) }
func (*User) ProtoMessage() {}
func (*User) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{4} }
func (m *User) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *User) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func init() {
proto.RegisterType((*CreateUserRequest)(nil), "user.CreateUserRequest")
proto.RegisterType((*CreateUserResponse)(nil), "user.CreateUserResponse")
proto.RegisterType((*GetUserRequest)(nil), "user.GetUserRequest")
proto.RegisterType((*GetUserResponse)(nil), "user.GetUserResponse")
proto.RegisterType((*User)(nil), "user.User")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for UserService service
type UserServiceClient interface {
CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error)
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
}
type userServiceClient struct {
cc *grpc.ClientConn
}
func NewUserServiceClient(cc *grpc.ClientConn) UserServiceClient {
return &userServiceClient{cc}
}
func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) {
out := new(CreateUserResponse)
err := grpc.Invoke(ctx, "/user.UserService/CreateUser", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) {
out := new(GetUserResponse)
err := grpc.Invoke(ctx, "/user.UserService/GetUser", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for UserService service
type UserServiceServer interface {
CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error)
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
}
func RegisterUserServiceServer(s *grpc.Server, srv UserServiceServer) {
s.RegisterService(&_UserService_serviceDesc, srv)
}
func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).CreateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/user.UserService/CreateUser",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).GetUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/user.UserService/GetUser",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).GetUser(ctx, req.(*GetUserRequest))
}
return interceptor(ctx, in, info, handler)
}
var _UserService_serviceDesc = grpc.ServiceDesc{
ServiceName: "user.UserService",
HandlerType: (*UserServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateUser",
Handler: _UserService_CreateUser_Handler,
},
{
MethodName: "GetUser",
Handler: _UserService_GetUser_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "services/user/user.proto",
}
func init() { proto.RegisterFile("services/user/user.proto", fileDescriptorUser) }
var fileDescriptorUser = []byte{
// 236 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x4e, 0x2d, 0x2a,
0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x2d, 0x4e, 0x2d, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25,
0xf9, 0x42, 0x2c, 0x20, 0xb6, 0x92, 0x3a, 0x97, 0xa0, 0x73, 0x51, 0x6a, 0x62, 0x49, 0x6a, 0x68,
0x71, 0x6a, 0x51, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x90, 0x10, 0x17, 0x4b, 0x5e, 0x62,
0x6e, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x98, 0xad, 0xe4, 0xcb, 0x25, 0x84, 0xac,
0xb0, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0x48, 0x8e, 0x0b, 0x6c, 0x0c, 0x58, 0x25, 0xb7, 0x11,
0x97, 0x1e, 0xd8, 0x7c, 0xb0, 0x0a, 0xb0, 0xb8, 0x90, 0x38, 0x17, 0x7b, 0x6a, 0x51, 0x51, 0x7c,
0x6e, 0x71, 0xba, 0x04, 0x13, 0xd8, 0x30, 0xb6, 0xd4, 0xa2, 0x22, 0xdf, 0xe2, 0x74, 0x25, 0x05,
0x2e, 0x3e, 0xf7, 0xd4, 0x12, 0x64, 0x4b, 0xf9, 0xb8, 0x98, 0x32, 0x53, 0xa0, 0x56, 0x32, 0x65,
0xa6, 0x28, 0x79, 0x71, 0xf1, 0xc3, 0x55, 0x50, 0x6a, 0x9b, 0x16, 0x17, 0x0b, 0x48, 0x19, 0xba,
0x1d, 0x70, 0x8f, 0x32, 0x21, 0x3c, 0x6a, 0xd4, 0xc5, 0xc8, 0xc5, 0x0d, 0x52, 0x1c, 0x0c, 0x09,
0x38, 0x21, 0x47, 0x2e, 0x2e, 0x84, 0xc7, 0x85, 0xc4, 0x21, 0x96, 0x62, 0x84, 0x99, 0x94, 0x04,
0xa6, 0x04, 0xc4, 0xd5, 0x4a, 0x0c, 0x42, 0x16, 0x5c, 0xec, 0x50, 0xaf, 0x08, 0x89, 0x40, 0x94,
0xa1, 0xfa, 0x5d, 0x4a, 0x14, 0x4d, 0x14, 0xa6, 0x33, 0x89, 0x0d, 0x1c, 0x57, 0xc6, 0x80, 0x00,
0x00, 0x00, 0xff, 0xff, 0xce, 0xde, 0xa3, 0x2e, 0xc7, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,87 @@
package user_grpctransport
import (
"fmt"
grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
)
// avoid import errors
var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.UserServiceServer {
options := []grpctransport.ServerOption{}
return &grpcServer{
createuser: grpctransport.NewServer(
ctx,
endpoints.CreateUserEndpoint,
decodeRequest,
encodeCreateUserResponse,
options...,
),
getuser: grpctransport.NewServer(
ctx,
endpoints.GetUserEndpoint,
decodeRequest,
encodeGetUserResponse,
options...,
),
}
}
type grpcServer struct {
createuser grpctransport.Handler
getuser grpctransport.Handler
}
func (s *grpcServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
_, rep, err := s.createuser.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.CreateUserResponse), nil
}
func encodeCreateUserResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.CreateUserResponse)
return resp, nil
}
func (s *grpcServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
_, rep, err := s.getuser.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.GetUserResponse), nil
}
func encodeGetUserResponse(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.GetUserResponse)
return resp, nil
}
func decodeRequest(ctx context.Context, grpcReq interface{}) (interface{}, error) {
return grpcReq, nil
}
type streamHandler interface {
Do(server interface{}, req interface{}) (err error)
}
type server struct {
e endpoints.StreamEndpoint
}
func (s server) Do(server interface{}, req interface{}) (err error) {
if err := s.e(server, req); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,64 @@
package user_httptransport
import (
"encoding/json"
context "golang.org/x/net/context"
"log"
"net/http"
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
)
func MakeCreateUserHandler(ctx context.Context, svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeCreateUserRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeCreateUserRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func MakeGetUserHandler(ctx context.Context, svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeGetUserRequest,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decodeGetUserRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.GetUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func RegisterHandlers(ctx context.Context, svc pb.UserServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/CreateUser\" (service=User)")
mux.Handle("/CreateUser", MakeCreateUserHandler(ctx, svc, endpoints.CreateUserEndpoint))
log.Println("new HTTP endpoint: \"/GetUser\" (service=User)")
mux.Handle("/GetUser", MakeGetUserHandler(ctx, svc, endpoints.GetUserEndpoint))
return nil
}

View File

@@ -0,0 +1,21 @@
package usersvc
import (
"fmt"
"golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
)
type Service struct{}
func New() pb.UserServiceServer { return &Service{} }
func (svc *Service) CreateUser(ctx context.Context, in *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
return nil, fmt.Errorf("not implemented")
}
func (svc *Service) GetUser(ctx context.Context, in *pb.GetUserRequest) (*pb.GetUserResponse, error) {
return nil, fmt.Errorf("not implemented")
}

View File

@@ -0,0 +1,29 @@
syntax = "proto3";
package user;
service UserService {
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) {}
rpc GetUser(GetUserRequest) returns (GetUserResponse) {}
}
message CreateUserRequest {
string name = 1;
}
message CreateUserResponse {
User user = 1;
string err_msg = 2;
}
message GetUserRequest {
string id = 1;
}
message GetUserResponse {
User user = 1;
string err_msg = 2;
}
message User {
string id = 1;
string name = 2;
}

View File

@@ -0,0 +1,56 @@
package {{.File.Package}}_clientgrpc
import (
"github.com/go-kit/kit/log"
context "golang.org/x/net/context"
"google.golang.org/grpc"
grpctransport "github.com/go-kit/kit/transport/grpc"
"github.com/go-kit/kit/endpoint"
jwt "github.com/go-kit/kit/auth/jwt"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
endpoints "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/endpoints"
)
{{$file:=.File}}
func New(conn *grpc.ClientConn, logger log.Logger) pb.{{.File.Package | title}}ServiceServer {
{{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}}
var {{.Name | lower}}Endpoint endpoint.Endpoint
{
{{.Name | lower}}Endpoint = grpctransport.NewClient(
conn,
"{{$file.Package}}.{{$file.Package | title}}Service",
"{{.Name}}",
Encode{{.Name}}Request,
Decode{{.Name}}Response,
pb.{{.Name}}Response{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))...,
).Endpoint()
}
{{end}}
{{end}}
return &endpoints.Endpoints {
{{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}}
{{.Name | title}}Endpoint: {{.Name | lower}}Endpoint,
{{end}}
{{end}}
}
}
{{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}}
func Encode{{.Name}}Request(_ context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.{{.Name}}Request)
return req, nil
}
func Decode{{.Name}}Response(_ context.Context, grpcResponse interface{}) (interface{}, error) {
response := grpcResponse.(*pb.{{.Name}}Response)
return response, nil
}
{{end}}
{{end}}

View File

@@ -0,0 +1,88 @@
package {{.File.Package}}_endpoints
{{$file := .File}}
import (
"fmt"
context "golang.org/x/net/context"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
"github.com/go-kit/kit/endpoint"
)
var _ = endpoint.Chain
var _ = fmt.Errorf
var _ = context.Background
type StreamEndpoint func(server interface{}, req interface{}) (err error)
type Endpoints struct {
{{range .Service.Method}}
{{if or (.ClientStreaming) (.ServerStreaming)}}
{{.Name}}Endpoint StreamEndpoint
{{else}}
{{.Name}}Endpoint endpoint.Endpoint
{{end}}
{{end}}
}
{{range .Service.Method}}
{{if .ServerStreaming}}
{{if .ClientStreaming}}
func (e *Endpoints){{.Name}}(server pb.{{$file.Package | title}}Service_{{.Name}}Server) error {
return fmt.Errorf("not implemented")
}
{{else}}
func (e *Endpoints){{.Name}}(in *pb.{{.Name}}Request, server pb.{{$file.Package | title}}Service_{{.Name}}Server) error {
return fmt.Errorf("not implemented")
}
{{end}}
{{else}}
{{if .ClientStreaming}}
func (e *Endpoints){{.Name}}(server pb.{{$file.Package | title}}Service_{{.Name}}Server) error {
return fmt.Errorf("not implemented")
}
{{else}}
func (e *Endpoints){{.Name}}(ctx context.Context, in *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) {
out, err := e.{{.Name}}Endpoint(ctx, in)
if err != nil {
return &pb.{{.OutputType | splitArray "." | last}}{ErrMsg: err.Error()}, err
}
return out.(*pb.{{.OutputType | splitArray "." | last}}), err
}
{{end}}
{{end}}
{{end}}
{{range .Service.Method}}
{{if or (.ServerStreaming) (.ClientStreaming)}}
func Make{{.Name}}Endpoint(svc pb.{{$file.Package | title}}ServiceServer) StreamEndpoint {
return func(server interface{}, request interface{}) error {
{{if .ClientStreaming}}
return svc.{{.Name}}(server.(pb.{{$file.Package | title}}Service_{{.Name}}Server))
{{else}}
return svc.{{.Name}}(request.(*pb.{{.Name}}Request), server.(pb.{{$file.Package | title}}Service_{{.Name}}Server))
{{end}}
}
}
{{else}}
func Make{{.Name}}Endpoint(svc pb.{{$file.Package | title}}ServiceServer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*pb.{{.InputType | splitArray "." | last}})
rep, err := svc.{{.Name}}(ctx, req)
if err != nil {
return &pb.{{.OutputType | splitArray "." | last}}{ErrMsg: err.Error()}, err
}
return rep, nil
}
}
{{end}}
{{end}}
func MakeEndpoints(svc pb.{{.File.Package | title}}ServiceServer) Endpoints {
return Endpoints{
{{range .Service.Method}}
{{.Name}}Endpoint: Make{{.Name}}Endpoint(svc),
{{end}}
}
}

View File

@@ -0,0 +1,92 @@
package {{.File.Package}}_grpctransport
{{$file := .File}}
import (
"fmt"
context "golang.org/x/net/context"
grpctransport "github.com/go-kit/kit/transport/grpc"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
endpoints "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/endpoints"
)
// avoid import errors
var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.{{.File.Package | title}}ServiceServer {
var options []grpctransport.ServerOption
_ = options
return &grpcServer{
{{range .Service.Method}}
{{if or (.ClientStreaming) (.ServerStreaming)}}
{{.Name | lower}}: &server{
e: endpoints.{{.Name}}Endpoint,
},
{{else}}
{{.Name | lower}}: grpctransport.NewServer(
ctx,
endpoints.{{.Name}}Endpoint,
decodeRequest,
encode{{.Name}}Response,
options...,
),
{{end}}
{{end}}
}
}
type grpcServer struct {
{{range .Service.Method}}
{{if or (.ClientStreaming) (.ServerStreaming)}}
{{.Name | lower}} streamHandler
{{else}}
{{.Name | lower}} grpctransport.Handler
{{end}}
{{end}}
}
{{range .Service.Method}}
{{if .ClientStreaming}}
func (s *grpcServer) {{.Name}}(server pb.{{$file.Package | title}}Service_{{.Name}}Server) error {
return s.{{.Name | lower}}.Do(server, nil)
}
{{else if .ServerStreaming}}
func (s *grpcServer) {{.Name}}(req *pb.{{.Name}}Request, server pb.{{$file.Package | title}}Service_{{.Name}}Server) error {
return s.{{.Name | lower}}.Do(server, req)
}
{{else}}
func (s *grpcServer) {{.Name}}(ctx context.Context, req *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) {
_, rep, err := s.{{.Name | lower}}.ServeGRPC(ctx, req)
if err != nil {
return nil, err
}
return rep.(*pb.{{.OutputType | splitArray "." | last}}), nil
}
func encode{{.Name}}Response(ctx context.Context, response interface{}) (interface{}, error) {
resp := response.(*pb.{{.OutputType | splitArray "." | last}})
return resp, nil
}
{{end}}
{{end}}
func decodeRequest(ctx context.Context, grpcReq interface{}) (interface{}, error) {
return grpcReq, nil
}
type streamHandler interface{
Do(server interface{}, req interface{}) (err error)
}
type server struct {
e endpoints.StreamEndpoint
}
func (s server) Do(server interface{}, req interface{}) (err error) {
if err := s.e(server, req); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,56 @@
package {{.File.Package}}_httptransport
{{$file := .File}}
import (
"log"
"net/http"
"encoding/json"
context "golang.org/x/net/context"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/endpoints"
)
var _ = log.Printf
var _ = gokit_endpoint.Chain
var _ = httptransport.NewClient
{{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}}
func Make{{.Name}}Handler(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decode{{.Name}}Request,
encodeResponse,
[]httptransport.ServerOption{}...,
)
}
func decode{{.Name}}Request(ctx context.Context, r *http.Request) (interface{}, error) {
var req pb.{{.InputType | splitArray "." | last}}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return &req, nil
}
{{end}}
{{end}}
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func RegisterHandlers(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
{{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}}
log.Println("new HTTP endpoint: \"/{{.Name}}\" (service={{$file.Package | title}})")
mux.Handle("/{{.Name}}", Make{{.Name}}Handler(ctx, svc, endpoints.{{.Name}}Endpoint))
{{end}}
{{end}}
return nil
}

13
examples/js-grpc/Makefile Normal file
View File

@@ -0,0 +1,13 @@
.PHONY: build
build:
mkdir -p output
protoc -I. --gotemplate_out=template_dir=templates,debug=true:output ./protos/*.proto
.PHONY: re
re: clean build
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,146 @@
// GENERATED CODE -- DO NOT EDIT!
'use strict';
var grpc = require('grpc');
var test_pb = require('./test_pb.js');
function serialize_test_TestNoStreamRequest(arg) {
if (!(arg instanceof test_pb.TestNoStreamRequest)) {
throw new Error('Expected argument of type test.TestNoStreamRequest');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestNoStreamRequest(buffer_arg) {
return test_pb.TestNoStreamRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestNoStreamReply(arg) {
if (!(arg instanceof test_pb.TestNoStreamReply)) {
throw new Error('Expected argument of type test.TestNoStreamReply');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestNoStreamReply(buffer_arg) {
return test_pb.TestNoStreamReply.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamRequestRequest(arg) {
if (!(arg instanceof test_pb.TestStreamRequestRequest)) {
throw new Error('Expected argument of type test.TestStreamRequestRequest');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamRequestRequest(buffer_arg) {
return test_pb.TestStreamRequestRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamRequestReply(arg) {
if (!(arg instanceof test_pb.TestStreamRequestReply)) {
throw new Error('Expected argument of type test.TestStreamRequestReply');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamRequestReply(buffer_arg) {
return test_pb.TestStreamRequestReply.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamReplyRequest(arg) {
if (!(arg instanceof test_pb.TestStreamReplyRequest)) {
throw new Error('Expected argument of type test.TestStreamReplyRequest');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamReplyRequest(buffer_arg) {
return test_pb.TestStreamReplyRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamReplyReply(arg) {
if (!(arg instanceof test_pb.TestStreamReplyReply)) {
throw new Error('Expected argument of type test.TestStreamReplyReply');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamReplyReply(buffer_arg) {
return test_pb.TestStreamReplyReply.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamBothRequest(arg) {
if (!(arg instanceof test_pb.TestStreamBothRequest)) {
throw new Error('Expected argument of type test.TestStreamBothRequest');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamBothRequest(buffer_arg) {
return test_pb.TestStreamBothRequest.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_test_TestStreamBothReply(arg) {
if (!(arg instanceof test_pb.TestStreamBothReply)) {
throw new Error('Expected argument of type test.TestStreamBothReply');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_test_TestStreamBothReply(buffer_arg) {
return test_pb.TestStreamBothReply.deserializeBinary(new Uint8Array(buffer_arg));
}
var TestServiceService = exports.TestServiceService = {
testNoStream: {
path: '/test.TestService/TestNoStream',
requestStream: false,
responseStream: false,
requestType: test_pb.TestNoStreamRequest,
responseType: test_pb.TestNoStreamReply,
requestSerialize: serialize_test_TestNoStreamRequest,
requestDeserialize: deserialize_test_TestNoStreamRequest,
responseSerialize: serialize_test_TestNoStreamReply,
responseDeserialize: deserialize_test_TestNoStreamReply,
},
testStreamRequest: {
path: '/test.TestService/TestStreamRequest',
requestStream: true,
responseStream: false,
requestType: test_pb.TestStreamRequestRequest,
responseType: test_pb.TestStreamRequestReply,
requestSerialize: serialize_test_TestStreamRequestRequest,
requestDeserialize: deserialize_test_TestStreamRequestRequest,
responseSerialize: serialize_test_TestStreamRequestReply,
responseDeserialize: deserialize_test_TestStreamRequestReply,
},
testStreamReply: {
path: '/test.TestService/TestStreamReply',
requestStream: false,
responseStream: true,
requestType: test_pb.TestStreamReplyRequest,
responseType: test_pb.TestStreamReplyReply,
requestSerialize: serialize_test_TestStreamReplyRequest,
requestDeserialize: deserialize_test_TestStreamReplyRequest,
responseSerialize: serialize_test_TestStreamReplyReply,
responseDeserialize: deserialize_test_TestStreamReplyReply,
},
testStreamBoth: {
path: '/test.TestService/TestStreamBoth',
requestStream: true,
responseStream: true,
requestType: test_pb.TestStreamBothRequest,
responseType: test_pb.TestStreamBothReply,
requestSerialize: serialize_test_TestStreamBothRequest,
requestDeserialize: deserialize_test_TestStreamBothRequest,
responseSerialize: serialize_test_TestStreamBothReply,
responseDeserialize: deserialize_test_TestStreamBothReply,
},
}
exports.TestServiceClient = grpc.makeGenericClientConstructor(TestServiceService);

View File

@@ -0,0 +1,34 @@
syntax = "proto3";
package test;
option go_package = "github.com/united-drivers/models/go/test;testpb";
service TestService {
rpc TestNoStream(TestNoStreamRequest) returns (TestNoStreamReply);
rpc TestStreamRequest(stream TestStreamRequestRequest) returns (TestStreamRequestReply);
rpc TestStreamReply(TestStreamReplyRequest) returns (stream TestStreamReplyReply);
rpc TestStreamBoth(stream TestStreamBothRequest) returns (stream TestStreamBothReply);
}
message TestMessage {
string a = 1;
int32 b = 2;
int64 c = 3;
float d = 4;
double e = 5;
repeated string n = 14;
repeated int32 o = 15;
repeated int64 p = 16;
repeated float q = 17;
repeated double r = 18;
}
message TestNoStreamRequest { TestMessage message = 1; }
message TestNoStreamReply { TestMessage message = 1; string err_msg = 2; }
message TestStreamRequestRequest { TestMessage message = 1; }
message TestStreamRequestReply { TestMessage message = 1; string err_msg = 2; }
message TestStreamReplyRequest { TestMessage message = 1; }
message TestStreamReplyReply { TestMessage message = 1; string err_msg = 2; }
message TestStreamBothRequest { TestMessage message = 1; }
message TestStreamBothReply { TestMessage message = 1; string err_msg = 2; }

View File

@@ -0,0 +1,47 @@
// GENERATED CODE -- DO NOT EDIT!
{{$Package:=.File.Package}}
'use strict';
var grpc = require('grpc');
var {{$Package}}_pb = require('./{{$Package}}_pb.js');
{{range .File.Service}}{{range .Method}}
function serialize_{{$Package}}_{{.InputType | splitArray "." | last}}(arg) {
if (!(arg instanceof {{$Package}}_pb.{{.InputType | splitArray "." | last}})) {
throw new Error('Expected argument of type {{$Package}}.{{.InputType | splitArray "." | last}}');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_{{$Package}}_{{.InputType | splitArray "." | last}}(buffer_arg) {
return {{$Package}}_pb.{{.InputType | splitArray "." | last}}.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_{{$Package}}_{{.OutputType | splitArray "." | last}}(arg) {
if (!(arg instanceof {{$Package}}_pb.{{.OutputType | splitArray "." | last}})) {
throw new Error('Expected argument of type {{$Package}}.{{.OutputType | splitArray "." | last}}');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_{{$Package}}_{{.OutputType | splitArray "." | last}}(buffer_arg) {
return {{$Package}}_pb.{{.OutputType | splitArray "." | last}}.deserializeBinary(new Uint8Array(buffer_arg));
}
{{end}}{{end}}
{{range .File.Service}}
var {{.Name}}Service = exports.{{.Name}}Service = {
{{$serviceName:=.Name}}
{{range .Method}}{{.Name | lowerCamelCase}}: {
path: '/{{$Package}}.{{$serviceName}}/{{.Name}}',
requestStream: {{.ClientStreaming | default "false"}},
responseStream: {{.ServerStreaming | default "false"}},
requestType: {{$Package}}_pb.{{.InputType | splitArray "." | last}},
responseType: {{$Package}}_pb.{{.OutputType | splitArray "." | last}},
requestSerialize: serialize_{{$Package}}_{{.InputType | splitArray "." | last}},
requestDeserialize: deserialize_{{$Package}}_{{.InputType | splitArray "." | last}},
responseSerialize: serialize_{{$Package}}_{{.OutputType | splitArray "." | last}},
responseDeserialize: deserialize_{{$Package}}_{{.OutputType | splitArray "." | last}},
},
{{end}}
}
exports.{{.Name}}Client = grpc.makeGenericClientConstructor({{.Name}}Service);{{end}}

View File

@@ -0,0 +1,44 @@
// GENERATED CODE -- DO NOT EDIT!
{{$Package:=.File.Package}}
'use strict';
var grpc = require('grpc');
var {{$Package}}_pb = require('./{{$Package}}_pb.js');
{{range .File.Service}}{{range .Method}}
function serialize_{{$Package}}_{{.InputType | splitArray "." | last}}(arg) {
if (!(arg instanceof {{$Package}}_pb.{{.InputType | splitArray "." | last}})) {
throw new Error('Expected argument of type {{$Package}}.{{.InputType | splitArray "." | last}}');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_{{$Package}}_{{.InputType | splitArray "." | last}}(buffer_arg) {
return {{$Package}}_pb.{{.InputType | splitArray "." | last}}.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_{{$Package}}_{{.OutputType | splitArray "." | last}}(arg) {
if (!(arg instanceof {{$Package}}_pb.{{.OutputType | splitArray "." | last}})) {
throw new Error('Expected argument of type {{$Package}}.{{.OutputType | splitArray "." | last}}');
}
return new Buffer(arg.serializeBinary());
}
function deserialize_{{$Package}}_{{.OutputType | splitArray "." | last}}(buffer_arg) {
return {{$Package}}_pb.{{.OutputType | splitArray "." | last}}.deserializeBinary(new Uint8Array(buffer_arg));
}
{{end}}{{end}}
{{range .File.Service}}
var {{.Name}}Service = exports.{{.Name}}Service = {
{{$serviceName:=.Name}}{{range .Method}}{{.Name | lowerCamelCase}}: {
path: '/{{$Package}}.{{$serviceName}}/{{.Name}}',
requestStream: {{.ClientStreaming | default "false"}},
responseStream: {{.ServerStreaming | default "false"}},
requestType: {{$Package}}_pb.{{.InputType | splitArray "." | last}},
responseType: {{$Package}}_pb.{{.OutputType | splitArray "." | last}},
requestSerialize: serialize_{{$Package}}_{{.InputType | splitArray "." | last}},
requestDeserialize: deserialize_{{$Package}}_{{.InputType | splitArray "." | last}},
responseSerialize: serialize_{{$Package}}_{{.OutputType | splitArray "." | last}},
responseDeserialize: deserialize_{{$Package}}_{{.OutputType | splitArray "." | last}},
},{{end}}
}
exports.{{.Name}}Client = grpc.makeGenericClientConstructor({{.Name}}Service);{{end}}

10
examples/k8s/Makefile Normal file
View File

@@ -0,0 +1,10 @@
SOURCES := $(shell find . -name "*.proto" -not -path ./vendor/\*)
TARGETS_K8S := $(foreach source, $(SOURCES), $(source)_k8s)
.PHONY: build
build: $(TARGETS_K8S)
$(TARGETS_K8S): %_k8s:
@mkdir -p $(dir $*)gen
protoc $(PROTOC_OPTS) --gotemplate_out=debug=true,template_dir=./templates:$(dir $*)gen "$*"

View File

@@ -0,0 +1,18 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
labels:
method: Hello-World-nginx
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- name: http
port: 80

11
examples/k8s/nginx.proto Normal file
View File

@@ -0,0 +1,11 @@
syntax = "proto3";
package nginx;
message Empty {
}
service Nginx {
rpc Hello(Empty) returns (Empty) {}
rpc World(Empty) returns (Empty) {}
}

View File

@@ -0,0 +1,18 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{.File.Package}}
labels:
method: {{range .Service.Method}}{{.Name}}-{{end}}{{.File.Package}}
spec:
replicas: 3
template:
metadata:
labels:
app: {{.File.Package}}
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: {{.File.Package}}
spec:
selector:
app: {{.File.Package}}
ports:
- name: http
port: 80

16
glide.lock generated
View File

@@ -1,15 +1,21 @@
hash: 6f0ff21a03d407a4a24bf299f8b80acc931e116457f5378867626c2de5c4265e
updated: 2016-11-06T18:32:18.567649309+01:00
hash: 488701437e53b39667ed5a84ed1500e727ea8d4902d804c3ea7eb50b1fc022a1
updated: 2016-12-21T10:24:42.512734471+01:00
imports:
- name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64
- name: github.com/golang/protobuf
version: 98fa357170587e470c5f27d3c3ea0947b71eb455
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
subpackages:
- proto
- protoc-gen-go/descriptor
- protoc-gen-go/generator
- protoc-gen-go/plugin
- name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40
- name: github.com/kr/fs
version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b
- name: github.com/moul/funcmap
version: 916897fb9db8a358561b3c2cdb7bd4d7cf2eb1c7
- name: github.com/Masterminds/sprig
version: 69011c0cd9b4d2e0733c4d9e2c8e2a5a0d0a2f2f
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
testImports: []

View File

@@ -7,5 +7,5 @@ import:
- protoc-gen-go/generator
- protoc-gen-go/plugin
- package: github.com/kr/fs
- package: github.com/moul/funcmap
version: ~1.0.0
- package: github.com/Masterminds/sprig
- package: github.com/huandu/xstrings

194
helpers.go Normal file
View File

@@ -0,0 +1,194 @@
package main
import (
"encoding/json"
"fmt"
"strings"
"text/template"
"github.com/Masterminds/sprig"
"github.com/huandu/xstrings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
options "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"
)
var ProtoHelpersFuncMap = template.FuncMap{
"string": func(i interface {
String() string
}) string {
return i.String()
},
"json": func(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
},
"prettyjson": func(v interface{}) string {
a, _ := json.MarshalIndent(v, "", " ")
return string(a)
},
"splitArray": func(sep string, s string) []string {
return strings.Split(s, sep)
},
"first": func(a []string) string {
return a[0]
},
"last": func(a []string) string {
return a[len(a)-1]
},
"upperFirst": func(s string) string {
return strings.ToUpper(s[:1]) + s[1:]
},
"lowerFirst": func(s string) string {
return strings.ToLower(s[:1]) + s[1:]
},
"camelCase": func(s string) string {
return xstrings.ToCamelCase(s)
},
"lowerCamelCase": func(s string) string {
cc := xstrings.ToCamelCase(s)
return strings.ToLower(cc[:1]) + cc[1:]
},
"snakeCase": func(s string) string {
return xstrings.ToSnakeCase(s)
},
"kebabCase": func(s string) string {
return strings.Replace(xstrings.ToSnakeCase(s), "_", "-", -1)
},
"getMessageType": getMessageType,
"isFieldMessage": isFieldMessage,
"isFieldRepeated": isFieldRepeated,
"goType": goType,
"httpVerb": httpVerb,
"httpPath": httpPath,
}
func init() {
for k, v := range sprig.TxtFuncMap() {
ProtoHelpersFuncMap[k] = v
}
}
func getMessageType(f *descriptor.FileDescriptorProto, name string) *descriptor.DescriptorProto {
for _, m := range f.MessageType {
// name usually contains the package name
if strings.HasSuffix(name, *m.Name) {
return m
}
}
return nil
}
func isFieldMessage(f *descriptor.FieldDescriptorProto) bool {
if f.Type != nil && *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
f.Label != nil && *f.Label != descriptor.FieldDescriptorProto_LABEL_REPEATED {
return true
}
return false
}
func isFieldRepeated(f *descriptor.FieldDescriptorProto) bool {
if f.Type != nil && f.Label != nil && *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return true
}
return false
}
func goType(pkg string, f *descriptor.FieldDescriptorProto) string {
switch *f.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
return "float64"
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
return "float32"
case descriptor.FieldDescriptorProto_TYPE_INT64:
return "int64"
case descriptor.FieldDescriptorProto_TYPE_UINT64:
return "uint64"
case descriptor.FieldDescriptorProto_TYPE_INT32:
return "uint32"
case descriptor.FieldDescriptorProto_TYPE_BOOL:
return "bool"
case descriptor.FieldDescriptorProto_TYPE_STRING:
return "string"
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return fmt.Sprintf("[]*%s.%s", pkg, shortType(*f.TypeName))
}
return fmt.Sprintf("*%s.%s", pkg, shortType(*f.TypeName))
case descriptor.FieldDescriptorProto_TYPE_BYTES:
return "byte"
case descriptor.FieldDescriptorProto_TYPE_UINT32:
return "uint32"
case descriptor.FieldDescriptorProto_TYPE_ENUM:
return fmt.Sprintf("*%s.%s", pkg, shortType(*f.TypeName))
default:
return "interface{}"
}
}
func shortType(s string) string {
t := strings.Split(s, ".")
return t[len(t)-1]
}
func httpPath(m *descriptor.MethodDescriptorProto) string {
ext, err := proto.GetExtension(m.Options, options.E_Http)
if err != nil {
return err.Error()
}
opts, ok := ext.(*options.HttpRule)
if !ok {
return fmt.Sprintf("extension is %T; want an HttpRule", ext)
}
switch t := opts.Pattern.(type) {
default:
return ""
case *options.HttpRule_Get:
return t.Get
case *options.HttpRule_Post:
return t.Post
case *options.HttpRule_Put:
return t.Put
case *options.HttpRule_Delete:
return t.Delete
case *options.HttpRule_Patch:
return t.Patch
case *options.HttpRule_Custom:
return t.Custom.Path
}
}
func httpVerb(m *descriptor.MethodDescriptorProto) string {
ext, err := proto.GetExtension(m.Options, options.E_Http)
if err != nil {
return err.Error()
}
opts, ok := ext.(*options.HttpRule)
if !ok {
return fmt.Sprintf("extension is %T; want an HttpRule", ext)
}
switch t := opts.Pattern.(type) {
default:
return ""
case *options.HttpRule_Get:
return "GET"
case *options.HttpRule_Post:
return "POST"
case *options.HttpRule_Put:
return "PUT"
case *options.HttpRule_Delete:
return "DELETE"
case *options.HttpRule_Patch:
return "PATCH"
case *options.HttpRule_Custom:
return t.Custom.Kind
}
}

12
main.go
View File

@@ -30,6 +30,7 @@ func main() {
// Parse parameters
templateDir := "./templates"
destinationDir := "."
debug := false
if parameter := g.Request.GetParameter(); parameter != "" {
for _, param := range strings.Split(parameter, ",") {
@@ -42,10 +43,15 @@ func main() {
case "template_dir":
templateDir = parts[1]
break
case "destination_dir":
destinationDir = parts[1]
break
case "debug":
if parts[1] == "true" {
switch strings.ToLower(parts[1]) {
case "true", "t":
debug = true
} else {
case "false", "f":
default:
log.Printf("Err: invalid value for debug: %q", parts[1])
}
break
@@ -58,7 +64,7 @@ func main() {
// Generate the encoders
for _, file := range g.Request.GetProtoFile() {
for _, service := range file.GetService() {
encoder := NewGenericTemplateBasedEncoder(templateDir, service, file, debug)
encoder := NewGenericTemplateBasedEncoder(templateDir, service, file, debug, destinationDir)
g.Response.File = append(g.Response.File, encoder.Files()...)
}
}

247
slides/README.md Normal file
View File

@@ -0,0 +1,247 @@
# [fit] Protobuf & Code Generation
### 2016, by Manfred Touron (@moul)
---
# overview
* go-kit is an amazing framework to develop strong micro services
* but it requires a lot of boilerplate code
* return on experience on go-kit boilerplate code generation
---
# protobuf?
* limited to exchanges (methods and models)
* extendable with plugins
* contract-based
* universal
---
# code generation?
* the good old ./generate.sh bash script
* go:generate
* make
* protobuf + [protoc-gen-gotemplate](https://github.com/moul/protoc-gen-gotemplate)
---
# go-kit
* protobuf-first, rpc-first service framework in Golang
* abstract services, endpoints, transports
* requires a lot of boilerplate code in multiple packages
---
# example: `session.proto`
```protobuf
syntax = "proto3";
package session;
service SessionService {
rpc Login(LoginRequest) returns (LoginResponse) {}
}
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
string token = 1;
string err_msg = 2;
}
```
---
# example: `session.go`
```go
package sessionsvc
import (
"fmt"
"golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
)
type Service struct{}
func New() pb.SessionServiceServer {
return &Service{}
}
func (svc *Service) Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) {
// custon code here
return nil, fmt.Errorf("not implemented")
}
```
---
##### example: `{{.File.Package}}/gen/transports/http/http.go.tmpl`
```go
// source: templates/{{.File.Package}}/gen/transports/http/http.go.tmpl
package {{.File.Package}}_httptransport
import (
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/pb"
)
```
```go
// result: services/user/gen/transports/http/http.go
package user_httptransport
import (
gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
)
```
---
##### example: `{{.File.Package}}/gen/transports/http/http.go.tmpl`
```go
// source: templates/{{.File.Package}}/gen/transports/http/http.go.tmpl
{{range .Service.Method}}
func Make{{.Name}}Handler(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decode{{.Name}}Request,
encode{{.Name}}Response,
[]httptransport.ServerOption{}...,
)
}
{{end}}
```
```go
// result: services/user/gen/transports/http/http.go
func MakeGetUserHandler(ctx context.Context, svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer(
ctx,
endpoint,
decodeGetUserRequest,
encodeGetUserResponse,
[]httptransport.ServerOption{}...,
)
}
```
---
##### example: `{{.File.Package}}/gen/transports/http/http.go.tmpl`
```go
// source: templates/{{.File.Package}}/gen/transports/http/http.go.tmpl
func RegisterHandlers(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
{{range .Service.Method}}
log.Println("new HTTP endpoint: \"/{{.Name}}\" (service={{$file.Package | title}})")
mux.Handle("/{{.Name}}", Make{{.Name}}Handler(ctx, svc, endpoints.{{.Name}}Endpoint))
{{end}}
return nil
}
```
```go
// result: services/user/gen/transports/http/http.go
func RegisterHandlers(ctx context.Context, svc pb.UserServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/CreateUser\" (service=User)")
mux.Handle("/CreateUser", MakeCreateUserHandler(ctx, svc, endpoints.CreateUserEndpoint))
log.Println("new HTTP endpoint: \"/GetUser\" (service=User)")
mux.Handle("/GetUser", MakeGetUserHandler(ctx, svc, endpoints.GetUserEndpoint))
return nil
}
```
---
#### `protoc --gogo_out=plugins=grpc:. ./services/*/*.proto`
---
#### `protoc --gotemplate_out=template_dir=./templates:services ./services/*/*.proto`
---
![fit](assets/session-wc.png)
---
![right fit](assets/wc.png)
## 3 services
## 6 methods
## 149 custom lines
## 1429 generated lines
## business focus
---
# generation usages
* go-kit boilerplate (see [examples/go-kit](https://github.com/moul/protoc-gen-gotemplate/tree/master/examples/go-kit))
* k8s configuration
* Dockerfile
* documentation
* unit-tests
* fun
---
# pros
* small custom codebase
* templates shipped with code
* hardly typed, no reflects
* genericity
* contrat terms (protobuf) respected
* not limited to a language
---
# cons
* the author needs to write its own templates
* sometimes difficult to generate valid code
* not enough helpers around the code generation yet
---
# improvement ideas
* Support protobufs extensions (i.e, annotations.probo)
* Generate one file from multiple services
* Add more helpers around the code generation
---
# conclusion
* Useful to keep everything standard
* The awesomeness of go-kit without the hassle of writing boilerplate code
* Always up-to-date with the contracts
---
# questions?
### github.com/moul/protoc-gen-gotemplate
### @moul

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
slides/assets/wc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
slides/slides.pdf Normal file

Binary file not shown.

1
vendor/github.com/Masterminds/sprig/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
vendor/

21
vendor/github.com/Masterminds/sprig/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,21 @@
language: go
go:
- 1.3
- 1.4
- 1.5
- tip
# Setting sudo access to false will let Travis CI use containers rather than
# VMs to run the tests. For more details see:
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
sudo: false
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always

16
vendor/github.com/Masterminds/sprig/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,16 @@
# Release 1.2.0 (2016-02-01)
- Added quote and squote
- Added b32enc and b32dec
- add now takes varargs
- biggest now takes varargs
# Release 1.1.0 (2015-12-29)
- Added #4: Added contains function. strings.Contains, but with the arguments
switched to simplify common pipelines. (thanks krancour)
- Added Travis-CI testing support
# Release 1.0.0 (2015-12-23)
- Initial release

20
vendor/github.com/Masterminds/sprig/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,20 @@
Sprig
Copyright (C) 2013 Masterminds
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.

238
vendor/github.com/Masterminds/sprig/README.md generated vendored Normal file
View File

@@ -0,0 +1,238 @@
# Sprig: Template functions for Go templates
The Go language comes with a [built-in template
language](http://golang.org/pkg/text/template/), but not
very many template functions. This library provides a group of commonly
used template functions.
It is inspired by the template functions found in
[Twig](http://twig.sensiolabs.org/documentation).
[![Build Status](https://travis-ci.org/Masterminds/sprig.svg?branch=master)](https://travis-ci.org/Masterminds/sprig)
## Usage
API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig), but
read on for standard usage.
### Load the Sprig library
To load the Sprig `FuncMap`:
```go
import (
"github.com/Masterminds/sprig"
"html/template"
)
// This example illustrates that the FuncMap *must* be set before the
// templates themselves are loaded.
tpl := template.Must(
template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html")
)
```
### Call the functions inside of templates
By convention, all functions are lowercase. This seems to follow the Go
idiom for template functions (as opposed to template methods, which are
TitleCase).
Example:
```
{{ "hello!" | upper | repeat 5 }}
```
Produces:
```
HELLO!HELLO!HELLO!HELLO!HELLO!
```
## Functions
### Date Functions
- date: Format a date, where a date is an integer type or a time.Time type, and
format is a time.Format formatting string.
- dateModify: Given a date, modify it with a duration: `date_modify "-1.5h" now`. If the duration doesn't
parse, it returns the time unaltered. See `time.ParseDuration` for info on duration strings.
- now: Current time.Time, for feeding into date-related functions.
- htmlDate: Format a date for use in the value field of an HTML "date" form element.
- dateInZone: Like date, but takes three arguments: format, timestamp,
timezone.
- htmlDateInZone: Like htmlDate, but takes two arguments: timestamp,
timezone.
### String Functions
- trim: strings.TrimSpace
- trimAll: strings.Trim, but with the argument order reversed `trimAll "$" "$5.00"` or `"$5.00 | trimAll "$"`
- trimSuffix: strings.TrimSuffix, but with the argument order reversed `trimSuffix "-" "5-"`
- trimPrefix: strings.TrimPrefix, but with the argument order reversed `trimPrefix "$" "$5"`
- upper: strings.ToUpper
- lower: strings.ToLower
- title: strings.Title
- repeat: strings.Repeat, but with the arguments switched: `repeat count str`. (This simplifies common pipelines)
- substr: Given string, start, and length, return a substr.
- nospace: Remove all spaces from a string. `h e l l o` becomes
`hello`.
- abbrev: Truncate a string with ellipses
- trunc: Truncate a string (no suffix). `trunc 5 "Hello World"` yields "hello".
- abbrevboth: Truncate both sides of a string with ellipses
- untitle: Remove title case
- intials: Given multiple words, return the first letter of each
word
- randAlphaNum: Generate a random alpha-numeric string
- randAlpha: Generate a random alphabetic string
- randAscii: Generate a random ASCII string, including symbols
- randNumeric: Generate a random numeric string
- wrap: Wrap text at the given column count
- wrapWith: Wrap text at the given column count, and with the given
string for a line terminator: `wrap 50 "\n\t" $string`
- contains: strings.Contains, but with the arguments switched: `contains "cat" "uncatch"`. (This simplifies common pipelines)
- hasPrefix: strings.hasPrefix, but with the arguments switched: `hasPrefix "cat" "catch"`.
- hasSuffix: strings.hasSuffix, but with the arguments switched: `hasSuffix "cat" "ducat"`.
- quote: Wrap strings in double quotes. `quote "a" "b"` returns `"a"
"b"`
- squote: Wrap strings in single quotes.
- cat: Concatenate strings, separating them by spaces. `cat $a $b $c`.
- indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar"
- replace: Replace an old with a new in a string: `$name | replace " " "-"`
- plural: Choose singular or plural based on length: `len $fish | plural
"one anchovy" "many anchovies"`
- uuidv4: Generate a UUID v4 string
- sha256sum: Generate a hex encoded sha256 hash of the input
### String Slice Functions:
- join: strings.Join, but as `join SEP SLICE`
- split: strings.Split, but as `split SEP STRING`. The results are returned
as a map with the indexes set to _N, where N is an integer starting from 0.
Use it like this: `{{$v := "foo/bar/baz" | split "/"}}{{$v._0}}` (Prints `foo`)
### Integer Slice Functions:
- until: Given an integer, returns a slice of counting integers from 0 to one
less than the given integer: `range $i, $e := until 5`
- untilStep: Given start, stop, and step, return an integer slice starting at
'start', stopping at `stop`, and incrementing by 'step'. This is the same
as Python's long-form of 'range'.
### Conversions:
- atoi: Convert a string to an integer. 0 if the integer could not be parsed.
- int: Convert a string or numeric to an int
- int64: Convert a string or numeric to an int64
- float64: Convert a string or numeric to a float64
### Defaults:
- default: Give a default value. Used like this: {{trim " "| default "empty"}}.
Since trim produces an empty string, the default value is returned. For
things with a length (strings, slices, maps), len(0) will trigger the default.
For numbers, the value 0 will trigger the default. For booleans, false will
trigger the default. For structs, the default is never returned (there is
no clear empty condition). For everything else, nil value triggers a default.
- empty: Returns true if the given value is the zero value for that
type. Structs are always non-empty.
### OS:
- env: Read an environment variable.
- expandenv: Expand all environment variables in a string.
### Encoding:
- b32enc: Encode a string into a Base32 string
- b32dec: Decode a string from a Base32 string
- b64enc: Encode a string into a Base64 string
- b64dec: Decode a string from a Base64 string
### Data Structures:
- tuple: A sequence of related objects. It is implemented as a
`[]interface{}`, where each item can be accessed using `index`.
- dict: Takes a list of name/values and returns a map[string]interface{}.
The first parameter is converted to a string and stored as a key, the
second parameter is treated as the value. And so on, with odds as keys and
evens as values. If the function call ends with an odd, the last key will
be assigned the empty string. Non-string keys are converted to strings as
follows: []byte are converted, fmt.Stringers will have String() called.
errors will have Error() called. All others will be passed through
fmt.Sprtinf("%v").
- set: Takes a dict, a key, and a value, and sets that key/value pair in
the dict. `set $dict $key $value`. For convenience, it returns the dict,
even though the dict was modified in place.
- unset: Takes a dict and a key, and deletes that key/value pair from the
dict. `unset $dict $key`. This returns the dict for convenience.
- hasKey: Takes a dict and a key, and returns boolean true if the key is in
the dict.
```
{{$t := tuple 1 "a" "foo"}}
{{index $t 2}}{{index $t 0 }}{{index $t 1}}
{{/* Prints foo1a *}}
```
### Reflection:
- typeOf: Takes an interface and returns a string representation of the type.
For pointers, this will return a type prefixed with an asterisk(`*`). So
a pointer to type `Foo` will be `*Foo`.
- typeIs: Compares an interface with a string name, and returns true if they match.
Note that a pointer will not match a reference. For example `*Foo` will not
match `Foo`.
- typeIsLike: returns true if the interface is of the given type, or
is a pointer to the given type.
- kindOf: Takes an interface and returns a string representation of its kind.
- kindIs: Returns true if the given string matches the kind of the given interface.
Note: None of these can test whether or not something implements a given
interface, since doing so would require compiling the interface in ahead of
time.
### Math Functions:
Integer functions will convert integers of any width to `int64`. If a
string is passed in, functions will attempt to conver with
`strconv.ParseInt(s, 1064)`. If this fails, the value will be treated as 0.
- add1: Increment an integer by 1
- add: Sum integers. `add 1 2 3` renders `6`
- sub: Subtract the second integer from the first
- div: Divide the first integer by the second
- mod: Module of first integer divided by second
- mul: Multiply integers integers
- max (biggest): Return the biggest of a series of integers. `max 1 2 3`
returns `3`.
- min: Return the smallest of a series of integers. `min 1 2 3` returns
`1`.
## Principles:
The following principles were used in deciding on which functions to add, and
determining how to implement them.
- Template functions should be used to build layout. Therefore, the following
types of operations are within the domain of template functions:
- Formatting
- Layout
- Simple type conversions
- Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
- Template functions should not return errors unless there is no way to print
a sensible value. For example, converting a string to an integer should not
produce an error if conversion fails. Instead, it should display a default
value that can be displayed.
- Simple math is necessary for grid layouts, pagers, and so on. Complex math
(anything other than arithmetic) should be done outside of templates.
- Template functions only deal with the data passed into them. They never retrieve
data from a source.
- Finally, do not override core Go template functions.

25
vendor/github.com/Masterminds/sprig/example_test.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
package sprig
import (
"fmt"
"os"
"text/template"
)
func Example() {
// Set up variables and template.
vars := map[string]interface{}{"Name": " John Jacob Jingleheimer Schmidt "}
tpl := `Hello {{.Name | trim | lower}}`
// Get the Sprig function map.
fmap := TxtFuncMap()
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
err := t.Execute(os.Stdout, vars)
if err != nil {
fmt.Printf("Error during template execution: %s", err)
return
}
// Output:
// Hello john jacob jingleheimer schmidt
}

895
vendor/github.com/Masterminds/sprig/functions.go generated vendored Normal file
View File

@@ -0,0 +1,895 @@
/*
Sprig: Template functions for Go.
This package contains a number of utility functions for working with data
inside of Go `html/template` and `text/template` files.
To add these functions, use the `template.Funcs()` method:
t := templates.New("foo").Funcs(sprig.FuncMap())
Note that you should add the function map before you parse any template files.
In several cases, Sprig reverses the order of arguments from the way they
appear in the standard library. This is to make it easier to pipe
arguments into functions.
Date Functions
- date FORMAT TIME: Format a date, where a date is an integer type or a time.Time type, and
format is a time.Format formatting string.
- dateModify: Given a date, modify it with a duration: `date_modify "-1.5h" now`. If the duration doesn't
parse, it returns the time unaltered. See `time.ParseDuration` for info on duration strings.
- now: Current time.Time, for feeding into date-related functions.
- htmlDate TIME: Format a date for use in the value field of an HTML "date" form element.
- dateInZone FORMAT TIME TZ: Like date, but takes three arguments: format, timestamp,
timezone.
- htmlDateInZone TIME TZ: Like htmlDate, but takes two arguments: timestamp,
timezone.
String Functions
- abbrev: Truncate a string with ellipses. `abbrev 5 "hello world"` yields "he..."
- abbrevboth: Abbreviate from both sides, yielding "...lo wo..."
- trunc: Truncate a string (no suffix). `trunc 5 "Hello World"` yields "hello".
- trim: strings.TrimSpace
- trimAll: strings.Trim, but with the argument order reversed `trimAll "$" "$5.00"` or `"$5.00 | trimAll "$"`
- trimSuffix: strings.TrimSuffix, but with the argument order reversed: `trimSuffix "-" "ends-with-"`
- trimPrefix: strings.TrimPrefix, but with the argument order reversed `trimPrefix "$" "$5"`
- upper: strings.ToUpper
- lower: strings.ToLower
- nospace: Remove all space characters from a string. `nospace "h e l l o"` becomes "hello"
- title: strings.Title
- untitle: Remove title casing
- repeat: strings.Repeat, but with the arguments switched: `repeat count str`. (This simplifies common pipelines)
- substr: Given string, start, and length, return a substr.
- initials: Given a multi-word string, return the initials. `initials "Matt Butcher"` returns "MB"
- randAlphaNum: Given a length, generate a random alphanumeric sequence
- randAlpha: Given a length, generate an alphabetic string
- randAscii: Given a length, generate a random ASCII string (symbols included)
- randNumeric: Given a length, generate a string of digits.
- wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"`
- wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "<br>", $html`
- contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines)
- hasPrefix: strings.hasPrefix, but with the arguments switched
- hasSuffix: strings.hasSuffix, but with the arguments switched
- quote: Wrap string(s) in double quotation marks, escape the contents by adding '\' before '"'.
- squote: Wrap string(s) in double quotation marks, does not escape content.
- cat: Concatenate strings, separating them by spaces. `cat $a $b $c`.
- indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar"
- replace: Replace an old with a new in a string: `$name | replace " " "-"`
- plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"`
- sha256sum: Generate a hex encoded sha256 hash of the input
String Slice Functions:
- join: strings.Join, but as `join SEP SLICE`
- split: strings.Split, but as `split SEP STRING`. The results are returned
as a map with the indexes set to _N, where N is an integer starting from 0.
Use it like this: `{{$v := "foo/bar/baz" | split "/"}}{{$v._0}}` (Prints `foo`)
Integer Slice Functions:
- until: Given an integer, returns a slice of counting integers from 0 to one
less than the given integer: `range $i, $e := until 5`
- untilStep: Given start, stop, and step, return an integer slice starting at
'start', stopping at `stop`, and incrementing by 'step. This is the same
as Python's long-form of 'range'.
Conversions:
- atoi: Convert a string to an integer. 0 if the integer could not be parsed.
- in64: Convert a string or another numeric type to an int64.
- int: Convert a string or another numeric type to an int.
- float64: Convert a string or another numeric type to a float64.
Defaults:
- default: Give a default value. Used like this: trim " "| default "empty".
Since trim produces an empty string, the default value is returned. For
things with a length (strings, slices, maps), len(0) will trigger the default.
For numbers, the value 0 will trigger the default. For booleans, false will
trigger the default. For structs, the default is never returned (there is
no clear empty condition). For everything else, nil value triggers a default.
- empty: Return true if the given value is the zero value for its type.
Caveats: structs are always non-empty. This should match the behavior of
{{if pipeline}}, but can be used inside of a pipeline.
OS:
- env: Resolve an environment variable
- expandenv: Expand a string through the environment
File Paths:
- base: Return the last element of a path. https://golang.org/pkg/path#Base
- dir: Remove the last element of a path. https://golang.org/pkg/path#Dir
- clean: Clean a path to the shortest equivalent name. (e.g. remove "foo/.."
from "foo/../bar.html") https://golang.org/pkg/path#Clean
- ext: https://golang.org/pkg/path#Ext
- isAbs: https://golang.org/pkg/path#IsAbs
Encoding:
- b64enc: Base 64 encode a string.
- b64dec: Base 64 decode a string.
Reflection:
- typeOf: Takes an interface and returns a string representation of the type.
For pointers, this will return a type prefixed with an asterisk(`*`). So
a pointer to type `Foo` will be `*Foo`.
- typeIs: Compares an interface with a string name, and returns true if they match.
Note that a pointer will not match a reference. For example `*Foo` will not
match `Foo`.
- typeIsLike: Compares an interface with a string name and returns true if
the interface is that `name` or that `*name`. In other words, if the given
value matches the given type or is a pointer to the given type, this returns
true.
- kindOf: Takes an interface and returns a string representation of its kind.
- kindIs: Returns true if the given string matches the kind of the given interface.
Note: None of these can test whether or not something implements a given
interface, since doing so would require compiling the interface in ahead of
time.
Data Structures:
- tuple: Takes an arbitrary list of items and returns a slice of items. Its
tuple-ish properties are mainly gained through the template idiom, and not
through an API provided here.
- dict: Takes a list of name/values and returns a map[string]interface{}.
The first parameter is converted to a string and stored as a key, the
second parameter is treated as the value. And so on, with odds as keys and
evens as values. If the function call ends with an odd, the last key will
be assigned the empty string. Non-string keys are converted to strings as
follows: []byte are converted, fmt.Stringers will have String() called.
errors will have Error() called. All others will be passed through
fmt.Sprtinf("%v").
- set: Takes a dict, a key, and a value, and sets that key/value pair in
the dict. `set $dict $key $value`. For convenience, it returns the dict,
even though the dict was modified in place.
- unset: Takes a dict and a key, and deletes that key/value pair from the
dict. `unset $dict $key`. This returns the dict for convenience.
- hasKey: Takes a dict and a key, and returns boolean true if the key is in
the dict.
Math Functions:
Integer functions will convert integers of any width to `int64`. If a
string is passed in, functions will attempt to convert with
`strconv.ParseInt(s, 1064)`. If this fails, the value will be treated as 0.
- add1: Increment an integer by 1
- add: Sum an arbitrary number of integers
- sub: Subtract the second integer from the first
- div: Divide the first integer by the second
- mod: Module of first integer divided by second
- mul: Multiply integers
- max: Return the biggest of a series of one or more integers
- min: Return the smallest of a series of one or more integers
- biggest: DEPRECATED. Return the biggest of a series of one or more integers
Crypto Functions:
- genPrivateKey: Generate a private key for the given cryptosystem. If no
argument is supplied, by default it will generate a private key using
the RSA algorithm. Accepted values are `rsa`, `dsa`, and `ecdsa`.
*/
package sprig
import (
"crypto/dsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base32"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"fmt"
"html/template"
"math"
"math/big"
"os"
"path"
"reflect"
"strconv"
"strings"
ttemplate "text/template"
"time"
util "github.com/aokoli/goutils"
uuid "github.com/satori/go.uuid"
)
// Produce the function map.
//
// Use this to pass the functions into the template engine:
//
// tpl := template.New("foo").Funcs(sprig.FuncMap))
//
func FuncMap() template.FuncMap {
return HtmlFuncMap()
}
// HermeticTextFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
func HermeticTxtFuncMap() ttemplate.FuncMap {
r := TxtFuncMap()
for _, name := range nonhermeticFunctions {
delete(r, name)
}
return r
}
// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
func HermeticHtmlFuncMap() template.FuncMap {
r := HtmlFuncMap()
for _, name := range nonhermeticFunctions {
delete(r, name)
}
return r
}
// TextFuncMap returns a 'text/template'.FuncMap
func TxtFuncMap() ttemplate.FuncMap {
return ttemplate.FuncMap(genericMap)
}
// HtmlFuncMap returns an 'html/template'.Funcmap
func HtmlFuncMap() template.FuncMap {
return template.FuncMap(genericMap)
}
// These functions are not guaranteed to evaluate to the same result for given input, because they
// refer to the environemnt or global state.
var nonhermeticFunctions = []string{
// Date functions
"date",
"date_in_zone",
"date_modify",
"now",
"htmlDate",
"htmlDateInZone",
"dateInZone",
"dateModify",
// Strings
"randAlphaNum",
"randAlpha",
"randAscii",
"randNumeric",
"uuidv4",
// OS
"env",
"expandenv",
}
var genericMap = map[string]interface{}{
"hello": func() string { return "Hello!" },
// Date functions
"date": date,
"date_in_zone": dateInZone,
"date_modify": dateModify,
"now": func() time.Time { return time.Now() },
"htmlDate": htmlDate,
"htmlDateInZone": htmlDateInZone,
"dateInZone": dateInZone,
"dateModify": dateModify,
// Strings
"abbrev": abbrev,
"abbrevboth": abbrevboth,
"trunc": trunc,
"trim": strings.TrimSpace,
"upper": strings.ToUpper,
"lower": strings.ToLower,
"title": strings.Title,
"untitle": untitle,
"substr": substring,
// Switch order so that "foo" | repeat 5
"repeat": func(count int, str string) string { return strings.Repeat(str, count) },
// Deprecated: Use trimAll.
"trimall": func(a, b string) string { return strings.Trim(b, a) },
// Switch order so that "$foo" | trimall "$"
"trimAll": func(a, b string) string { return strings.Trim(b, a) },
"trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
"trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
"nospace": util.DeleteWhiteSpace,
"initials": initials,
"randAlphaNum": randAlphaNumeric,
"randAlpha": randAlpha,
"randAscii": randAscii,
"randNumeric": randNumeric,
"swapcase": util.SwapCase,
"wrap": func(l int, s string) string { return util.Wrap(s, l) },
"wrapWith": func(l int, sep, str string) string { return util.WrapCustom(str, l, sep, true) },
// Switch order so that "foobar" | contains "foo"
"contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
"hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
"hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
"quote": quote,
"squote": squote,
"cat": cat,
"indent": indent,
"replace": replace,
"plural": plural,
"sha256sum": sha256sum,
// Wrap Atoi to stop errors.
"atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
"int64": toInt64,
"int": toInt,
"float64": toFloat64,
//"gt": func(a, b int) bool {return a > b},
//"gte": func(a, b int) bool {return a >= b},
//"lt": func(a, b int) bool {return a < b},
//"lte": func(a, b int) bool {return a <= b},
// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
"split": split,
"until": until,
"untilStep": untilStep,
// VERY basic arithmetic.
"add1": func(i interface{}) int64 { return toInt64(i) + 1 },
"add": func(i ...interface{}) int64 {
var a int64 = 0
for _, b := range i {
a += toInt64(b)
}
return a
},
"sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
"div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
"mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
"mul": func(a interface{}, v ...interface{}) int64 {
val := toInt64(a)
for _, b := range v {
val = val * toInt64(b)
}
return val
},
"biggest": max,
"max": max,
"min": min,
// string slices. Note that we reverse the order b/c that's better
// for template processing.
"join": func(sep string, ss []string) string { return strings.Join(ss, sep) },
// Defaults
"default": dfault,
"empty": empty,
// Reflection
"typeOf": typeOf,
"typeIs": typeIs,
"typeIsLike": typeIsLike,
"kindOf": kindOf,
"kindIs": kindIs,
// OS:
"env": func(s string) string { return os.Getenv(s) },
"expandenv": func(s string) string { return os.ExpandEnv(s) },
// File Paths:
"base": path.Base,
"dir": path.Dir,
"clean": path.Clean,
"ext": path.Ext,
"isAbs": path.IsAbs,
// Encoding:
"b64enc": base64encode,
"b64dec": base64decode,
"b32enc": base32encode,
"b32dec": base32decode,
// Data Structures:
"tuple": tuple,
"dict": dict,
"set": set,
"unset": unset,
"hasKey": hasKey,
// Crypto:
"genPrivateKey": generatePrivateKey,
// UUIDs:
"uuidv4": uuidv4,
}
func split(sep, orig string) map[string]string {
parts := strings.Split(orig, sep)
res := make(map[string]string, len(parts))
for i, v := range parts {
res["_"+strconv.Itoa(i)] = v
}
return res
}
// substring creates a substring of the given string.
//
// If start is < 0, this calls string[:length].
//
// If start is >= 0 and length < 0, this calls string[start:]
//
// Otherwise, this calls string[start, length].
func substring(start, length int, s string) string {
if start < 0 {
return s[:length]
}
if length < 0 {
return s[start:]
}
return s[start:length]
}
// Given a format and a date, format the date string.
//
// Date can be a `time.Time` or an `int, int32, int64`.
// In the later case, it is treated as seconds since UNIX
// epoch.
func date(fmt string, date interface{}) string {
return dateInZone(fmt, date, "Local")
}
func htmlDate(date interface{}) string {
return dateInZone("2006-01-02", date, "Local")
}
func htmlDateInZone(date interface{}, zone string) string {
return dateInZone("2006-01-02", date, zone)
}
func dateInZone(fmt string, date interface{}, zone string) string {
var t time.Time
switch date := date.(type) {
default:
t = time.Now()
case time.Time:
t = date
case int64:
t = time.Unix(date, 0)
case int:
t = time.Unix(int64(date), 0)
case int32:
t = time.Unix(int64(date), 0)
}
loc, err := time.LoadLocation(zone)
if err != nil {
loc, _ = time.LoadLocation("UTC")
}
return t.In(loc).Format(fmt)
}
func dateModify(fmt string, date time.Time) time.Time {
d, err := time.ParseDuration(fmt)
if err != nil {
return date
}
return date.Add(d)
}
func max(a interface{}, i ...interface{}) int64 {
aa := toInt64(a)
for _, b := range i {
bb := toInt64(b)
if bb > aa {
aa = bb
}
}
return aa
}
func min(a interface{}, i ...interface{}) int64 {
aa := toInt64(a)
for _, b := range i {
bb := toInt64(b)
if bb < aa {
aa = bb
}
}
return aa
}
// dfault checks whether `given` is set, and returns default if not set.
//
// This returns `d` if `given` appears not to be set, and `given` otherwise.
//
// For numeric types 0 is unset.
// For strings, maps, arrays, and slices, len() = 0 is considered unset.
// For bool, false is unset.
// Structs are never considered unset.
//
// For everything else, including pointers, a nil value is unset.
func dfault(d interface{}, given ...interface{}) interface{} {
if empty(given) || empty(given[0]) {
return d
}
return given[0]
}
// empty returns true if the given value has the zero value for its type.
func empty(given interface{}) bool {
g := reflect.ValueOf(given)
if !g.IsValid() {
return true
}
// Basically adapted from text/template.isTrue
switch g.Kind() {
default:
return g.IsNil()
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
return g.Len() == 0
case reflect.Bool:
return g.Bool() == false
case reflect.Complex64, reflect.Complex128:
return g.Complex() == 0
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return g.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return g.Uint() == 0
case reflect.Float32, reflect.Float64:
return g.Float() == 0
case reflect.Struct:
return false
}
return true
}
// typeIs returns true if the src is the type named in target.
func typeIs(target string, src interface{}) bool {
return target == typeOf(src)
}
func typeIsLike(target string, src interface{}) bool {
t := typeOf(src)
return target == t || "*"+target == t
}
func typeOf(src interface{}) string {
return fmt.Sprintf("%T", src)
}
func kindIs(target string, src interface{}) bool {
return target == kindOf(src)
}
func kindOf(src interface{}) string {
return reflect.ValueOf(src).Kind().String()
}
func base64encode(v string) string {
return base64.StdEncoding.EncodeToString([]byte(v))
}
func base64decode(v string) string {
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return err.Error()
}
return string(data)
}
func base32encode(v string) string {
return base32.StdEncoding.EncodeToString([]byte(v))
}
func base32decode(v string) string {
data, err := base32.StdEncoding.DecodeString(v)
if err != nil {
return err.Error()
}
return string(data)
}
func abbrev(width int, s string) string {
if width < 4 {
return s
}
r, _ := util.Abbreviate(s, width)
return r
}
func abbrevboth(left, right int, s string) string {
if right < 4 || left > 0 && right < 7 {
return s
}
r, _ := util.AbbreviateFull(s, left, right)
return r
}
func initials(s string) string {
// Wrap this just to eliminate the var args, which templates don't do well.
return util.Initials(s)
}
func randAlphaNumeric(count int) string {
// It is not possible, it appears, to actually generate an error here.
r, _ := util.RandomAlphaNumeric(count)
return r
}
func randAlpha(count int) string {
r, _ := util.RandomAlphabetic(count)
return r
}
func randAscii(count int) string {
r, _ := util.RandomAscii(count)
return r
}
func randNumeric(count int) string {
r, _ := util.RandomNumeric(count)
return r
}
func untitle(str string) string {
return util.Uncapitalize(str)
}
func quote(str ...interface{}) string {
out := make([]string, len(str))
for i, s := range str {
out[i] = fmt.Sprintf("%q", strval(s))
}
return strings.Join(out, " ")
}
func squote(str ...interface{}) string {
out := make([]string, len(str))
for i, s := range str {
out[i] = fmt.Sprintf("'%v'", s)
}
return strings.Join(out, " ")
}
func tuple(v ...interface{}) []interface{} {
return v
}
func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
d[key] = value
return d
}
func unset(d map[string]interface{}, key string) map[string]interface{} {
delete(d, key)
return d
}
func hasKey(d map[string]interface{}, key string) bool {
_, ok := d[key]
return ok
}
func dict(v ...interface{}) map[string]interface{} {
dict := map[string]interface{}{}
lenv := len(v)
for i := 0; i < lenv; i += 2 {
key := strval(v[i])
if i+1 >= lenv {
dict[key] = ""
continue
}
dict[key] = v[i+1]
}
return dict
}
func strval(v interface{}) string {
switch v := v.(type) {
case string:
return v
case []byte:
return string(v)
case error:
return v.Error()
case fmt.Stringer:
return v.String()
default:
return fmt.Sprintf("%v", v)
}
}
// toFloat64 converts 64-bit floats
func toFloat64(v interface{}) float64 {
if str, ok := v.(string); ok {
iv, err := strconv.ParseFloat(str, 64)
if err != nil {
return 0
}
return iv
}
val := reflect.Indirect(reflect.ValueOf(v))
switch val.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
return float64(val.Int())
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
return float64(val.Uint())
case reflect.Uint, reflect.Uint64:
return float64(val.Uint())
case reflect.Float32, reflect.Float64:
return val.Float()
case reflect.Bool:
if val.Bool() == true {
return 1
}
return 0
default:
return 0
}
}
func toInt(v interface{}) int {
//It's not optimal. Bud I don't want duplicate toInt64 code.
return int(toInt64(v))
}
// toInt64 converts integer types to 64-bit integers
func toInt64(v interface{}) int64 {
if str, ok := v.(string); ok {
iv, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return 0
}
return iv
}
val := reflect.Indirect(reflect.ValueOf(v))
switch val.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
return val.Int()
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
return int64(val.Uint())
case reflect.Uint, reflect.Uint64:
tv := val.Uint()
if tv <= math.MaxInt64 {
return int64(tv)
}
// TODO: What is the sensible thing to do here?
return math.MaxInt64
case reflect.Float32, reflect.Float64:
return int64(val.Float())
case reflect.Bool:
if val.Bool() == true {
return 1
}
return 0
default:
return 0
}
}
func generatePrivateKey(typ string) string {
var priv interface{}
var err error
switch typ {
case "", "rsa":
// good enough for government work
priv, err = rsa.GenerateKey(rand.Reader, 4096)
case "dsa":
key := new(dsa.PrivateKey)
// again, good enough for government work
if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
return fmt.Sprintf("failed to generate dsa params: %s", err)
}
err = dsa.GenerateKey(key, rand.Reader)
priv = key
case "ecdsa":
// again, good enough for government work
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
default:
return "Unknown type " + typ
}
if err != nil {
return fmt.Sprintf("failed to generate private key: %s", err)
}
return string(pem.EncodeToMemory(pemBlockForKey(priv)))
}
type DSAKeyFormat struct {
Version int
P, Q, G, Y, X *big.Int
}
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
case *dsa.PrivateKey:
val := DSAKeyFormat{
P: k.P, Q: k.Q, G: k.G,
Y: k.Y, X: k.X,
}
bytes, _ := asn1.Marshal(val)
return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
case *ecdsa.PrivateKey:
b, _ := x509.MarshalECPrivateKey(k)
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
default:
return nil
}
}
func trunc(c int, s string) string {
if len(s) <= c {
return s
}
return s[0:c]
}
func cat(v ...interface{}) string {
r := strings.TrimSpace(strings.Repeat("%v ", len(v)))
return fmt.Sprintf(r, v...)
}
func indent(spaces int, v string) string {
pad := strings.Repeat(" ", spaces)
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
}
func replace(old, new, src string) string {
return strings.Replace(src, old, new, -1)
}
func plural(one, many string, count int) string {
if count == 1 {
return one
}
return many
}
func sha256sum(input string) string {
hash := sha256.Sum256([]byte(input))
return hex.EncodeToString(hash[:])
}
func until(count int) []int {
step := 1
if count < 0 {
step = -1
}
return untilStep(0, count, step)
}
func untilStep(start, stop, step int) []int {
v := []int{}
if stop < start {
if step >= 0 {
return v
}
for i := start; i > stop; i += step {
v = append(v, i)
}
return v
}
if step <= 0 {
return v
}
for i := start; i < stop; i += step {
v = append(v, i)
}
return v
}
// uuidv4 provides a safe and secure UUID v4 implementation
func uuidv4() string {
return fmt.Sprintf("%s", uuid.NewV4())
}

731
vendor/github.com/Masterminds/sprig/functions_test.go generated vendored Normal file
View File

@@ -0,0 +1,731 @@
package sprig
import (
"bytes"
"encoding/base32"
"encoding/base64"
"fmt"
"math/rand"
"os"
"strings"
"testing"
"text/template"
"github.com/aokoli/goutils"
"github.com/stretchr/testify/assert"
)
// This is woefully incomplete. Please help.
func TestSubstr(t *testing.T) {
tpl := `{{"fooo" | substr 0 3 }}`
if err := runt(tpl, "foo"); err != nil {
t.Error(err)
}
}
func TestTrunc(t *testing.T) {
tpl := `{{ "foooooo" | trunc 3 }}`
if err := runt(tpl, "foo"); err != nil {
t.Error(err)
}
}
func TestQuote(t *testing.T) {
tpl := `{{quote "a" "b" "c"}}`
if err := runt(tpl, `"a" "b" "c"`); err != nil {
t.Error(err)
}
tpl = `{{quote "\"a\"" "b" "c"}}`
if err := runt(tpl, `"\"a\"" "b" "c"`); err != nil {
t.Error(err)
}
tpl = `{{quote 1 2 3 }}`
if err := runt(tpl, `"1" "2" "3"`); err != nil {
t.Error(err)
}
}
func TestSquote(t *testing.T) {
tpl := `{{squote "a" "b" "c"}}`
if err := runt(tpl, `'a' 'b' 'c'`); err != nil {
t.Error(err)
}
tpl = `{{squote 1 2 3 }}`
if err := runt(tpl, `'1' '2' '3'`); err != nil {
t.Error(err)
}
}
func TestContains(t *testing.T) {
// Mainly, we're just verifying the paramater order swap.
tests := []string{
`{{if contains "cat" "fair catch"}}1{{end}}`,
`{{if hasPrefix "cat" "catch"}}1{{end}}`,
`{{if hasSuffix "cat" "ducat"}}1{{end}}`,
}
for _, tt := range tests {
if err := runt(tt, "1"); err != nil {
t.Error(err)
}
}
}
func TestTrim(t *testing.T) {
tests := []string{
`{{trim " 5.00 "}}`,
`{{trimAll "$" "$5.00$"}}`,
`{{trimPrefix "$" "$5.00"}}`,
`{{trimSuffix "$" "5.00$"}}`,
}
for _, tt := range tests {
if err := runt(tt, "5.00"); err != nil {
t.Error(err)
}
}
}
func TestAdd(t *testing.T) {
tpl := `{{ 3 | add 1 2}}`
if err := runt(tpl, `6`); err != nil {
t.Error(err)
}
}
func TestMul(t *testing.T) {
tpl := `{{ 1 | mul "2" 3 "4"}}`
if err := runt(tpl, `24`); err != nil {
t.Error(err)
}
}
func TestHtmlDate(t *testing.T) {
t.Skip()
tpl := `{{ htmlDate 0}}`
if err := runt(tpl, "1970-01-01"); err != nil {
t.Error(err)
}
}
func TestBiggest(t *testing.T) {
tpl := `{{ biggest 1 2 3 345 5 6 7}}`
if err := runt(tpl, `345`); err != nil {
t.Error(err)
}
tpl = `{{ max 345}}`
if err := runt(tpl, `345`); err != nil {
t.Error(err)
}
}
func TestMin(t *testing.T) {
tpl := `{{ min 1 2 3 345 5 6 7}}`
if err := runt(tpl, `1`); err != nil {
t.Error(err)
}
tpl = `{{ min 345}}`
if err := runt(tpl, `345`); err != nil {
t.Error(err)
}
}
func TestDefault(t *testing.T) {
tpl := `{{"" | default "foo"}}`
if err := runt(tpl, "foo"); err != nil {
t.Error(err)
}
tpl = `{{default "foo" 234}}`
if err := runt(tpl, "234"); err != nil {
t.Error(err)
}
tpl = `{{default "foo" 2.34}}`
if err := runt(tpl, "2.34"); err != nil {
t.Error(err)
}
tpl = `{{ .Nothing | default "123" }}`
if err := runt(tpl, "123"); err != nil {
t.Error(err)
}
tpl = `{{ default "123" }}`
if err := runt(tpl, "123"); err != nil {
t.Error(err)
}
}
func TestToFloat64(t *testing.T) {
target := float64(102)
if target != toFloat64(int8(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64(int(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64(int32(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64(int16(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64(int64(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64("102") {
t.Errorf("Expected 102")
}
if 0 != toFloat64("frankie") {
t.Errorf("Expected 0")
}
if target != toFloat64(uint16(102)) {
t.Errorf("Expected 102")
}
if target != toFloat64(uint64(102)) {
t.Errorf("Expected 102")
}
if 102.1234 != toFloat64(float64(102.1234)) {
t.Errorf("Expected 102.1234")
}
if 1 != toFloat64(true) {
t.Errorf("Expected 102")
}
}
func TestToInt64(t *testing.T) {
target := int64(102)
if target != toInt64(int8(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(int(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(int32(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(int16(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(int64(102)) {
t.Errorf("Expected 102")
}
if target != toInt64("102") {
t.Errorf("Expected 102")
}
if 0 != toInt64("frankie") {
t.Errorf("Expected 0")
}
if target != toInt64(uint16(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(uint64(102)) {
t.Errorf("Expected 102")
}
if target != toInt64(float64(102.1234)) {
t.Errorf("Expected 102")
}
if 1 != toInt64(true) {
t.Errorf("Expected 102")
}
}
func TestToInt(t *testing.T) {
target := int(102)
if target != toInt(int8(102)) {
t.Errorf("Expected 102")
}
if target != toInt(int(102)) {
t.Errorf("Expected 102")
}
if target != toInt(int32(102)) {
t.Errorf("Expected 102")
}
if target != toInt(int16(102)) {
t.Errorf("Expected 102")
}
if target != toInt(int64(102)) {
t.Errorf("Expected 102")
}
if target != toInt("102") {
t.Errorf("Expected 102")
}
if 0 != toInt("frankie") {
t.Errorf("Expected 0")
}
if target != toInt(uint16(102)) {
t.Errorf("Expected 102")
}
if target != toInt(uint64(102)) {
t.Errorf("Expected 102")
}
if target != toInt(float64(102.1234)) {
t.Errorf("Expected 102")
}
if 1 != toInt(true) {
t.Errorf("Expected 102")
}
}
func TestEmpty(t *testing.T) {
tpl := `{{if empty 1}}1{{else}}0{{end}}`
if err := runt(tpl, "0"); err != nil {
t.Error(err)
}
tpl = `{{if empty 0}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty ""}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty 0.0}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty false}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
dict := map[string]interface{}{"top": map[string]interface{}{}}
tpl = `{{if empty .top.NoSuchThing}}1{{else}}0{{end}}`
if err := runtv(tpl, "1", dict); err != nil {
t.Error(err)
}
tpl = `{{if empty .bottom.NoSuchThing}}1{{else}}0{{end}}`
if err := runtv(tpl, "1", dict); err != nil {
t.Error(err)
}
}
func TestSplit(t *testing.T) {
tpl := `{{$v := "foo$bar$baz" | split "$"}}{{$v._0}}`
if err := runt(tpl, "foo"); err != nil {
t.Error(err)
}
}
type fixtureTO struct {
Name, Value string
}
func TestTypeOf(t *testing.T) {
f := &fixtureTO{"hello", "world"}
tpl := `{{typeOf .}}`
if err := runtv(tpl, "*sprig.fixtureTO", f); err != nil {
t.Error(err)
}
}
func TestKindOf(t *testing.T) {
tpl := `{{kindOf .}}`
f := fixtureTO{"hello", "world"}
if err := runtv(tpl, "struct", f); err != nil {
t.Error(err)
}
f2 := []string{"hello"}
if err := runtv(tpl, "slice", f2); err != nil {
t.Error(err)
}
var f3 *fixtureTO = nil
if err := runtv(tpl, "ptr", f3); err != nil {
t.Error(err)
}
}
func TestTypeIs(t *testing.T) {
f := &fixtureTO{"hello", "world"}
tpl := `{{if typeIs "*sprig.fixtureTO" .}}t{{else}}f{{end}}`
if err := runtv(tpl, "t", f); err != nil {
t.Error(err)
}
f2 := "hello"
if err := runtv(tpl, "f", f2); err != nil {
t.Error(err)
}
}
func TestTypeIsLike(t *testing.T) {
f := "foo"
tpl := `{{if typeIsLike "string" .}}t{{else}}f{{end}}`
if err := runtv(tpl, "t", f); err != nil {
t.Error(err)
}
// Now make a pointer. Should still match.
f2 := &f
if err := runtv(tpl, "t", f2); err != nil {
t.Error(err)
}
}
func TestKindIs(t *testing.T) {
f := &fixtureTO{"hello", "world"}
tpl := `{{if kindIs "ptr" .}}t{{else}}f{{end}}`
if err := runtv(tpl, "t", f); err != nil {
t.Error(err)
}
f2 := "hello"
if err := runtv(tpl, "f", f2); err != nil {
t.Error(err)
}
}
func TestEnv(t *testing.T) {
os.Setenv("FOO", "bar")
tpl := `{{env "FOO"}}`
if err := runt(tpl, "bar"); err != nil {
t.Error(err)
}
}
func TestExpandEnv(t *testing.T) {
os.Setenv("FOO", "bar")
tpl := `{{expandenv "Hello $FOO"}}`
if err := runt(tpl, "Hello bar"); err != nil {
t.Error(err)
}
}
func TestBase64EncodeDecode(t *testing.T) {
magicWord := "coffee"
expect := base64.StdEncoding.EncodeToString([]byte(magicWord))
if expect == magicWord {
t.Fatal("Encoder doesn't work.")
}
tpl := `{{b64enc "coffee"}}`
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
tpl = fmt.Sprintf("{{b64dec %q}}", expect)
if err := runt(tpl, magicWord); err != nil {
t.Error(err)
}
}
func TestBase32EncodeDecode(t *testing.T) {
magicWord := "coffee"
expect := base32.StdEncoding.EncodeToString([]byte(magicWord))
if expect == magicWord {
t.Fatal("Encoder doesn't work.")
}
tpl := `{{b32enc "coffee"}}`
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
tpl = fmt.Sprintf("{{b32dec %q}}", expect)
if err := runt(tpl, magicWord); err != nil {
t.Error(err)
}
}
func TestGoutils(t *testing.T) {
tests := map[string]string{
`{{abbrev 5 "hello world"}}`: "he...",
`{{abbrevboth 5 10 "1234 5678 9123"}}`: "...5678...",
`{{nospace "h e l l o "}}`: "hello",
`{{untitle "First Try"}}`: "first try", //https://youtu.be/44-RsrF_V_w
`{{initials "First Try"}}`: "FT",
`{{wrap 5 "Hello World"}}`: "Hello\nWorld",
`{{wrapWith 5 "\t" "Hello World"}}`: "Hello\tWorld",
}
for k, v := range tests {
t.Log(k)
if err := runt(k, v); err != nil {
t.Errorf("Error on tpl %s: %s", err)
}
}
}
func TestRandom(t *testing.T) {
// One of the things I love about Go:
goutils.RANDOM = rand.New(rand.NewSource(1))
// Because we're using a random number generator, we need these to go in
// a predictable sequence:
if err := runt(`{{randAlphaNum 5}}`, "9bzRv"); err != nil {
t.Errorf("Error on tpl %s: %s", err)
}
if err := runt(`{{randAlpha 5}}`, "VjwGe"); err != nil {
t.Errorf("Error on tpl %s: %s", err)
}
if err := runt(`{{randAscii 5}}`, "1KA5p"); err != nil {
t.Errorf("Error on tpl %s: %s", err)
}
if err := runt(`{{randNumeric 5}}`, "26018"); err != nil {
t.Errorf("Error on tpl %s: %s", err)
}
}
func TestCat(t *testing.T) {
tpl := `{{$b := "b"}}{{"c" | cat "a" $b}}`
if err := runt(tpl, "a b c"); err != nil {
t.Error(err)
}
}
func TestIndent(t *testing.T) {
tpl := `{{indent 4 "a\nb\nc"}}`
if err := runt(tpl, " a\n b\n c"); err != nil {
t.Error(err)
}
}
func TestReplace(t *testing.T) {
tpl := `{{"I Am Henry VIII" | replace " " "-"}}`
if err := runt(tpl, "I-Am-Henry-VIII"); err != nil {
t.Error(err)
}
}
func TestPlural(t *testing.T) {
tpl := `{{$num := len "two"}}{{$num}} {{$num | plural "1 char" "chars"}}`
if err := runt(tpl, "3 chars"); err != nil {
t.Error(err)
}
tpl = `{{len "t" | plural "cheese" "%d chars"}}`
if err := runt(tpl, "cheese"); err != nil {
t.Error(err)
}
}
func TestSha256Sum(t *testing.T) {
tpl := `{{"abc" | sha256sum}}`
if err := runt(tpl, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); err != nil {
t.Error(err)
}
}
func TestTuple(t *testing.T) {
tpl := `{{$t := tuple 1 "a" "foo"}}{{index $t 2}}{{index $t 0 }}{{index $t 1}}`
if err := runt(tpl, "foo1a"); err != nil {
t.Error(err)
}
}
func TestDict(t *testing.T) {
tpl := `{{$d := dict 1 2 "three" "four" 5}}{{range $k, $v := $d}}{{$k}}{{$v}}{{end}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if len(out) != 12 {
t.Errorf("Expected length 12, got %d", len(out))
}
// dict does not guarantee ordering because it is backed by a map.
if !strings.Contains(out, "12") {
t.Error("Expected grouping 12")
}
if !strings.Contains(out, "threefour") {
t.Error("Expected grouping threefour")
}
if !strings.Contains(out, "5") {
t.Error("Expected 5")
}
tpl = `{{$t := dict "I" "shot" "the" "albatross"}}{{$t.the}} {{$t.I}}`
if err := runt(tpl, "albatross shot"); err != nil {
t.Error(err)
}
}
func TestUnset(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- $_ := unset $d "two" -}}
{{- range $k, $v := $d}}{{$k}}{{$v}}{{- end -}}
`
expect := "one1"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestHasKey(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- if hasKey $d "one" -}}1{{- end -}}
`
expect := "1"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestSet(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- $_ := set $d "two" 2 -}}
{{- $_ := set $d "three" 3 -}}
{{- if hasKey $d "one" -}}{{$d.one}}{{- end -}}
{{- if hasKey $d "two" -}}{{$d.two}}{{- end -}}
{{- if hasKey $d "three" -}}{{$d.three}}{{- end -}}
`
expect := "123"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestUntil(t *testing.T) {
tests := map[string]string{
`{{range $i, $e := until 5}}{{$i}}{{$e}}{{end}}`: "0011223344",
`{{range $i, $e := until -5}}{{$i}}{{$e}} {{end}}`: "00 1-1 2-2 3-3 4-4 ",
}
for tpl, expect := range tests {
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
}
func TestUntilStep(t *testing.T) {
tests := map[string]string{
`{{range $i, $e := untilStep 0 5 1}}{{$i}}{{$e}}{{end}}`: "0011223344",
`{{range $i, $e := untilStep 3 6 1}}{{$i}}{{$e}}{{end}}`: "031425",
`{{range $i, $e := untilStep 0 -10 -2}}{{$i}}{{$e}} {{end}}`: "00 1-2 2-4 3-6 4-8 ",
`{{range $i, $e := untilStep 3 0 1}}{{$i}}{{$e}}{{end}}`: "",
`{{range $i, $e := untilStep 3 99 0}}{{$i}}{{$e}}{{end}}`: "",
`{{range $i, $e := untilStep 3 99 -1}}{{$i}}{{$e}}{{end}}`: "",
`{{range $i, $e := untilStep 3 0 0}}{{$i}}{{$e}}{{end}}`: "",
}
for tpl, expect := range tests {
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
}
func TestBase(t *testing.T) {
assert.NoError(t, runt(`{{ base "foo/bar" }}`, "bar"))
}
func TestDir(t *testing.T) {
assert.NoError(t, runt(`{{ dir "foo/bar/baz" }}`, "foo/bar"))
}
func TestIsAbs(t *testing.T) {
assert.NoError(t, runt(`{{ isAbs "/foo" }}`, "true"))
assert.NoError(t, runt(`{{ isAbs "foo" }}`, "false"))
}
func TestClean(t *testing.T) {
assert.NoError(t, runt(`{{ clean "/foo/../foo/../bar" }}`, "/bar"))
}
func TestExt(t *testing.T) {
assert.NoError(t, runt(`{{ ext "/foo/bar/baz.txt" }}`, ".txt"))
}
func TestDelete(t *testing.T) {
fmap := TxtFuncMap()
delete(fmap, "split")
if _, ok := fmap["split"]; ok {
t.Error("Failed to delete split from map")
}
}
// NOTE(bacongobbler): this test is really _slow_ because of how long it takes to compute
// and generate a new crypto key.
func TestGenPrivateKey(t *testing.T) {
// test that calling by default generates an RSA private key
tpl := `{{genPrivateKey ""}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "RSA PRIVATE KEY") {
t.Error("Expected RSA PRIVATE KEY")
}
// test all acceptable arguments
tpl = `{{genPrivateKey "rsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "RSA PRIVATE KEY") {
t.Error("Expected RSA PRIVATE KEY")
}
tpl = `{{genPrivateKey "dsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "DSA PRIVATE KEY") {
t.Error("Expected DSA PRIVATE KEY")
}
tpl = `{{genPrivateKey "ecdsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "EC PRIVATE KEY") {
t.Error("Expected EC PRIVATE KEY")
}
// test bad
tpl = `{{genPrivateKey "bad"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if out != "Unknown type bad" {
t.Error("Expected type 'bad' to be an unknown crypto algorithm")
}
// ensure that we can base64 encode the string
tpl = `{{genPrivateKey "rsa" | b64enc}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
}
func TestUUIDGeneration(t *testing.T) {
tpl := `{{uuidv4}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if len(out) != 36 {
t.Error("Expected UUID of length 36")
}
out2, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if out == out2 {
t.Error("Expected subsequent UUID generations to be different")
}
}
func runt(tpl, expect string) error {
return runtv(tpl, expect, map[string]string{})
}
func runtv(tpl, expect string, vars interface{}) error {
fmap := TxtFuncMap()
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
var b bytes.Buffer
err := t.Execute(&b, vars)
if err != nil {
return err
}
if expect != b.String() {
return fmt.Errorf("Expected '%s', got '%s'", expect, b.String())
}
return nil
}
func runRaw(tpl string, vars interface{}) (string, error) {
fmap := TxtFuncMap()
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
var b bytes.Buffer
err := t.Execute(&b, vars)
if err != nil {
return "", err
}
return b.String(), nil
}

8
vendor/github.com/Masterminds/sprig/glide.lock generated vendored Normal file
View File

@@ -0,0 +1,8 @@
hash: a8ed42a70698b4d199b5de7fa33e7c48251651e6ccf97d007f546cb72a5d0f8f
updated: 2016-09-30T12:23:39.512939213-06:00
imports:
- name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
testImports: []

5
vendor/github.com/Masterminds/sprig/glide.yaml generated vendored Normal file
View File

@@ -0,0 +1,5 @@
package: github.com/Masterminds/sprig
import:
- package: github.com/aokoli/goutils
- package: github.com/satori/go.uuid
version: ^1.1.0

202
vendor/github.com/aokoli/goutils/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

72
vendor/github.com/aokoli/goutils/README.md generated vendored Normal file
View File

@@ -0,0 +1,72 @@
GoUtils
===========
GoUtils provides users with utility functions to manipulate strings in various ways. It is a Go implementation of some
string manipulation libraries of Java Apache Commons. GoUtils includes the following Java Apache Commons classes:
* WordUtils
* RandomStringUtils
* StringUtils (partial implementation)
## Installation
If you have Go set up on your system, from the GOPATH directory within the command line/terminal, enter this:
go get github.com/aokoli/goutils
If you do not have Go set up on your system, please follow the [Go installation directions from the documenation](http://golang.org/doc/install), and then follow the instructions above to install GoUtils.
## Documentation
GoUtils doc is available here: [![GoDoc](https://godoc.org/github.com/aokoli/goutils?status.png)](https://godoc.org/github.com/aokoli/goutils)
## Usage
The code snippets below show examples of how to use GoUtils. Some functions return errors while others do not. The first instance below, which does not return an error, is the `Initials` function (located within the `wordutils.go` file).
package main
import (
"fmt"
"github.com/aokoli/goutils"
)
func main() {
// EXAMPLE 1: A goutils function which returns no errors
fmt.Println (goutils.Initials("John Doe Foo")) // Prints out "JDF"
}
Some functions return errors mainly due to illegal arguements used as parameters. The code example below illustrates how to deal with function that returns an error. In this instance, the function is the `Random` function (located within the `randomstringutils.go` file).
package main
import (
"fmt"
"github.com/aokoli/goutils"
)
func main() {
// EXAMPLE 2: A goutils function which returns an error
rand1, err1 := goutils.Random (-1, 0, 0, true, true)
if err1 != nil {
fmt.Println(err1) // Prints out error message because -1 was entered as the first parameter in goutils.Random(...)
} else {
fmt.Println(rand1)
}
}
## License
GoUtils is licensed under the Apache License, Version 2.0. Please check the LICENSE.txt file or visit http://www.apache.org/licenses/LICENSE-2.0 for a copy of the license.
## Issue Reporting
Make suggestions or report issues using the Git issue tracker: https://github.com/aokoli/goutils/issues
## Website
* [GoUtils webpage](http://aokoli.github.io/goutils/)
## Mailing List
Contact [okolialex@gmail.com](mailto:okolialex@mail.com) to be added to the mailing list. You will get updates on the
status of the project and the potential direction it will be heading.

259
vendor/github.com/aokoli/goutils/randomstringutils.go generated vendored Normal file
View File

@@ -0,0 +1,259 @@
/*
Copyright 2014 Alexander Okoli
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package goutils
import (
"fmt"
"unicode"
"math"
"math/rand"
"time"
)
// Provides the time-based seed used to generate random #s
var RANDOM = rand.New(rand.NewSource(time.Now().UnixNano()))
/*
RandomNonAlphaNumeric creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of all characters (ASCII/Unicode values between 0 to 2,147,483,647 (math.MaxInt32)).
Parameter:
count - the length of random string to create
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomNonAlphaNumeric (count int) (string, error) {
return RandomAlphaNumericCustom(count, false, false)
}
/*
RandomAscii creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of characters whose ASCII value is between 32 and 126 (inclusive).
Parameter:
count - the length of random string to create
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomAscii(count int) (string, error) {
return Random(count, 32, 127, false, false)
}
/*
RandomNumeric creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of numeric characters.
Parameter:
count - the length of random string to create
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomNumeric (count int) (string, error) {
return Random(count, 0, 0, false, true)
}
/*
RandomAlphabetic creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
Parameters:
count - the length of random string to create
letters - if true, generated string may include alphabetic characters
numbers - if true, generated string may include numeric characters
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomAlphabetic (count int) (string, error) {
return Random(count, 0, 0, true, false)
}
/*
RandomAlphaNumeric creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of alpha-numeric characters.
Parameter:
count - the length of random string to create
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomAlphaNumeric (count int) (string, error) {
return Random(count, 0, 0, true, true)
}
/*
RandomAlphaNumericCustom creates a random string whose length is the number of characters specified.
Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
Parameters:
count - the length of random string to create
letters - if true, generated string may include alphabetic characters
numbers - if true, generated string may include numeric characters
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func RandomAlphaNumericCustom (count int, letters bool, numbers bool) (string, error) {
return Random(count, 0, 0, letters, numbers)
}
/*
Random creates a random string based on a variety of options, using default source of randomness.
This method has exactly the same semantics as RandomSeed(int, int, int, bool, bool, []char, *rand.Rand), but
instead of using an externally supplied source of randomness, it uses the internal *rand.Rand instance.
Parameters:
count - the length of random string to create
start - the position in set of chars (ASCII/Unicode int) to start at
end - the position in set of chars (ASCII/Unicode int) to end before
letters - if true, generated string may include alphabetic characters
numbers - if true, generated string may include numeric characters
chars - the set of chars to choose randoms from. If nil, then it will use the set of all chars.
Returns:
string - the random string
error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
*/
func Random (count int, start int, end int, letters bool, numbers bool, chars ...rune) (string, error) {
return RandomSeed (count, start, end, letters, numbers, chars, RANDOM)
}
/*
RandomSeed creates a random string based on a variety of options, using supplied source of randomness.
If the parameters start and end are both 0, start and end are set to ' ' and 'z', the ASCII printable characters, will be used,
unless letters and numbers are both false, in which case, start and end are set to 0 and math.MaxInt32, respectively.
If chars is not nil, characters stored in chars that are between start and end are chosen.
This method accepts a user-supplied *rand.Rand instance to use as a source of randomness. By seeding a single *rand.Rand instance
with a fixed seed and using it for each call, the same random sequence of strings can be generated repeatedly and predictably.
Parameters:
count - the length of random string to create
start - the position in set of chars (ASCII/Unicode decimals) to start at
end - the position in set of chars (ASCII/Unicode decimals) to end before
letters - if true, generated string may include alphabetic characters
numbers - if true, generated string may include numeric characters
chars - the set of chars to choose randoms from. If nil, then it will use the set of all chars.
random - a source of randomness.
Returns:
string - the random string
error - an error stemming from invalid parameters: if count < 0; or the provided chars array is empty; or end <= start; or end > len(chars)
*/
func RandomSeed (count int, start int, end int, letters bool, numbers bool, chars []rune, random *rand.Rand) (string, error) {
if count == 0 {
return "", nil
} else if count < 0 {
err := fmt.Errorf("randomstringutils illegal argument: Requested random string length %v is less than 0.", count) // equiv to err := errors.New("...")
return "", err
}
if chars != nil && len(chars) == 0 {
err := fmt.Errorf("randomstringutils illegal argument: The chars array must not be empty")
return "", err
}
if start == 0 && end == 0 {
if chars != nil {
end = len(chars)
} else {
if !letters && !numbers {
end = math.MaxInt32
} else {
end = 'z' + 1
start = ' '
}
}
} else {
if end <= start {
err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) must be greater than start (%v)", end, start)
return "", err
}
if chars != nil && end > len(chars) {
err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) cannot be greater than len(chars) (%v)", end, len(chars))
return "", err
}
}
buffer := make([]rune, count)
gap := end - start
// high-surrogates range, (\uD800-\uDBFF) = 55296 - 56319
// low-surrogates range, (\uDC00-\uDFFF) = 56320 - 57343
for count != 0 {
count--
var ch rune
if chars == nil {
ch = rune(random.Intn(gap) + start)
} else {
ch = chars[random.Intn(gap) + start]
}
if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers {
if ch >= 56320 && ch <= 57343 { // low surrogate range
if count == 0 {
count++
} else {
// Insert low surrogate
buffer[count] = ch
count--
// Insert high surrogate
buffer[count] = rune(55296 + random.Intn(128))
}
} else if ch >= 55296 && ch <= 56191 { // High surrogates range (Partial)
if count == 0 {
count++
} else {
// Insert low surrogate
buffer[count] = rune(56320 + random.Intn(128))
count--
// Insert high surrogate
buffer[count] = ch
}
} else if ch >= 56192 && ch <= 56319 {
// private high surrogate, skip it
count++
} else {
// not one of the surrogates*
buffer[count] = ch
}
} else {
count++
}
}
return string(buffer), nil
}

View File

@@ -0,0 +1,95 @@
package goutils
import (
"testing"
"fmt"
"math/rand"
)
// ****************************** TESTS ********************************************
func TestRandomSeed(t *testing.T) {
// count, start, end, letters, numbers := 5, 0, 0, true, true
random := rand.New(rand.NewSource(10))
out := "3ip9v"
// Test 1: Simulating RandomAlphaNumeric(count int)
if x, _ := RandomSeed (5, 0, 0, true, true, nil, random); x != out {
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, true, true, nil, random, x, out)
}
// Test 2: Simulating RandomAlphabetic(count int)
out = "MBrbj"
if x, _ := RandomSeed (5, 0, 0, true, false, nil, random); x != out {
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, true, false, nil, random, x, out)
}
// Test 3: Simulating RandomNumeric(count int)
out = "88935"
if x, _ := RandomSeed (5, 0, 0, false, true, nil, random); x != out {
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, false, true, nil, random, x, out)
}
// Test 4: Simulating RandomAscii(count int)
out = "H_I;E"
if x, _ := RandomSeed (5, 32, 127, false, false, nil, random); x != out {
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 32, 127, false, false, nil, random, x, out)
}
// Test 5: Simulating RandomSeed(...) with custom chars
chars := []rune {'1','2','3','a','b','c'}
out = "2b2ca"
if x, _ := RandomSeed (5, 0, 0, false, false, chars, random); x != out {
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, false, false, chars, random, x, out)
}
}
// ****************************** EXAMPLES ********************************************
func ExampleRandomSeed() {
var seed int64 = 10 // If you change this seed #, the random sequence below will change
random := rand.New(rand.NewSource(seed))
chars := []rune {'1','2','3','a','b','c'}
rand1, _ := RandomSeed (5, 0, 0, true, true, nil, random) // RandomAlphaNumeric (Alphabets and numbers possible)
rand2, _ := RandomSeed (5, 0, 0, true, false, nil, random) // RandomAlphabetic (Only alphabets)
rand3, _ := RandomSeed (5, 0, 0, false, true, nil, random) // RandomNumeric (Only numbers)
rand4, _ := RandomSeed (5, 32, 127, false, false, nil, random) // RandomAscii (Alphabets, numbers, and other ASCII chars)
rand5, _ := RandomSeed (5, 0, 0, true, true, chars, random) // RandomSeed with custom characters
fmt.Println(rand1)
fmt.Println(rand2)
fmt.Println(rand3)
fmt.Println(rand4)
fmt.Println(rand5)
// Output:
// 3ip9v
// MBrbj
// 88935
// H_I;E
// 2b2ca
}

232
vendor/github.com/aokoli/goutils/stringutils.go generated vendored Normal file
View File

@@ -0,0 +1,232 @@
/*
Copyright 2014 Alexander Okoli
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package goutils
import (
"fmt"
"unicode"
"bytes"
"strings"
)
// Typically returned by functions where a searched item cannot be found
const INDEX_NOT_FOUND = -1
/*
Abbreviate abbreviates a string using ellipses. This will turn the string "Now is the time for all good men" into "Now is the time for..."
Specifically, the algorithm is as follows:
- If str is less than maxWidth characters long, return it.
- Else abbreviate it to (str[0:maxWidth - 3] + "...").
- If maxWidth is less than 4, return an illegal argument error.
- In no case will it return a string of length greater than maxWidth.
Parameters:
str - the string to check
maxWidth - maximum length of result string, must be at least 4
Returns:
string - abbreviated string
error - if the width is too small
*/
func Abbreviate (str string, maxWidth int) (string, error) {
return AbbreviateFull(str, 0, maxWidth)
}
/*
AbbreviateFull abbreviates a string using ellipses. This will turn the string "Now is the time for all good men" into "...is the time for..."
This function works like Abbreviate(string, int), but allows you to specify a "left edge" offset. Note that this left edge is not
necessarily going to be the leftmost character in the result, or the first character following the ellipses, but it will appear
somewhere in the result.
In no case will it return a string of length greater than maxWidth.
Parameters:
str - the string to check
offset - left edge of source string
maxWidth - maximum length of result string, must be at least 4
Returns:
string - abbreviated string
error - if the width is too small
*/
func AbbreviateFull (str string, offset int, maxWidth int) (string, error) {
if str == "" {
return "", nil
}
if maxWidth < 4 {
err := fmt.Errorf("stringutils illegal argument: Minimum abbreviation width is 4")
return "", err
}
if len(str) <= maxWidth {
return str, nil
}
if offset > len(str) {
offset = len(str)
}
if len(str) - offset < (maxWidth - 3) { // 15 - 5 < 10 - 3 = 10 < 7
offset = len(str) - (maxWidth - 3)
}
abrevMarker := "..."
if offset <= 4 {
return str[0:maxWidth - 3] + abrevMarker, nil// str.substring(0, maxWidth - 3) + abrevMarker;
}
if maxWidth < 7 {
err := fmt.Errorf("stringutils illegal argument: Minimum abbreviation width with offset is 7")
return "", err
}
if (offset + maxWidth - 3) < len(str) { // 5 + (10-3) < 15 = 12 < 15
abrevStr, _ := Abbreviate(str[offset:len(str)], (maxWidth - 3))
return abrevMarker + abrevStr, nil// abrevMarker + abbreviate(str.substring(offset), maxWidth - 3);
}
return abrevMarker + str[(len(str) - (maxWidth - 3)):len(str)], nil // abrevMarker + str.substring(str.length() - (maxWidth - 3));
}
/*
DeleteWhiteSpace deletes all whitespaces from a string as defined by unicode.IsSpace(rune).
It returns the string without whitespaces.
Parameter:
str - the string to delete whitespace from, may be nil
Returns:
the string without whitespaces
*/
func DeleteWhiteSpace(str string) string {
if str == "" {
return str
}
sz := len(str)
var chs bytes.Buffer
count := 0
for i := 0; i < sz; i++ {
ch := rune(str[i])
if !unicode.IsSpace(ch) {
chs.WriteRune(ch)
count++
}
}
if count == sz {
return str
}
return chs.String()
}
/*
IndexOfDifference compares two strings, and returns the index at which the strings begin to differ.
Parameters:
str1 - the first string
str2 - the second string
Returns:
the index where str1 and str2 begin to differ; -1 if they are equal
*/
func IndexOfDifference(str1 string, str2 string) int {
if str1 == str2 {
return INDEX_NOT_FOUND
}
if IsEmpty(str1) || IsEmpty(str2) {
return 0
}
var i int;
for i = 0; i < len(str1) && i < len(str2); i++ {
if rune(str1[i]) != rune(str2[i]) {
break
}
}
if i < len(str2) || i < len(str1) {
return i
}
return INDEX_NOT_FOUND
}
/*
IsBlank checks if a string is whitespace or empty (""). Observe the following behavior:
goutils.IsBlank("") = true
goutils.IsBlank(" ") = true
goutils.IsBlank("bob") = false
goutils.IsBlank(" bob ") = false
Parameter:
str - the string to check
Returns:
true - if the string is whitespace or empty ("")
*/
func IsBlank(str string) bool {
strLen := len(str)
if str == "" || strLen == 0 {
return true
}
for i := 0; i < strLen; i++ {
if unicode.IsSpace(rune(str[i])) == false {
return false
}
}
return true
}
/*
IndexOf returns the index of the first instance of sub in str, with the search beginning from the
index start point specified. -1 is returned if sub is not present in str.
An empty string ("") will return -1 (INDEX_NOT_FOUND). A negative start position is treated as zero.
A start position greater than the string length returns -1.
Parameters:
str - the string to check
sub - the substring to find
start - the start position; negative treated as zero
Returns:
the first index where the sub string was found (always >= start)
*/
func IndexOf(str string, sub string, start int) int {
if (start < 0) {
start = 0
}
if len(str) < start {
return INDEX_NOT_FOUND
}
if IsEmpty(str) || IsEmpty(sub) {
return INDEX_NOT_FOUND
}
partialIndex := strings.Index(str[start:len(str)], sub)
if partialIndex == -1 {
return INDEX_NOT_FOUND
}
return partialIndex + start
}
// IsEmpty checks if a string is empty (""). Returns true if empty, and false otherwise.
func IsEmpty(str string) bool {
return len(str) == 0
}

329
vendor/github.com/aokoli/goutils/stringutils_test.go generated vendored Normal file
View File

@@ -0,0 +1,329 @@
package goutils
import (
"testing"
"fmt"
)
// ****************************** TESTS ********************************************
func TestAbbreviate(t *testing.T) {
// Test 1
in := "abcdefg"
out := "abc..."
maxWidth := 6
if x, _ := Abbreviate(in, maxWidth); x != out {
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
}
// Test 2
out = "abcdefg"
maxWidth = 7
if x, _ := Abbreviate(in, maxWidth); x != out {
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
}
// Test 3
out = "a..."
maxWidth = 4
if x, _ := Abbreviate(in, maxWidth); x != out {
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
}
}
func TestAbbreviateFull(t *testing.T) {
// Test 1
in := "abcdefghijklmno"
out := "abcdefg..."
offset := -1
maxWidth := 10
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
}
// Test 2
out = "...fghi..."
offset = 5
maxWidth = 10
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
}
// Test 3
out = "...ijklmno"
offset = 12
maxWidth = 10
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
}
}
func TestIndexOf(t *testing.T) {
// Test 1
str := "abcafgka"
sub := "a"
start := 0
out := 0
if x := IndexOf(str, sub, start); x != out {
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
}
// Test 2
start = 1
out = 3
if x := IndexOf(str, sub, start); x != out {
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
}
// Test 3
start = 4
out = 7
if x := IndexOf(str, sub, start); x != out {
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
}
// Test 4
sub = "z"
out = -1
if x := IndexOf(str, sub, start); x != out {
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
}
}
func TestIsBlank(t *testing.T) {
// Test 1
str := ""
out := true
if x := IsBlank(str); x != out {
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
}
// Test 2
str = " "
out = true
if x := IsBlank(str); x != out {
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
}
// Test 3
str = " abc "
out = false
if x := IsBlank(str); x != out {
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
}
}
func TestDeleteWhiteSpace(t *testing.T) {
// Test 1
str := " a b c "
out := "abc"
if x := DeleteWhiteSpace(str); x != out {
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
}
// Test 2
str = " "
out = ""
if x := DeleteWhiteSpace(str); x != out {
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
}
}
func TestIndexOfDifference(t *testing.T) {
str1 := "abc"
str2 := "a_c"
out := 1
if x := IndexOfDifference(str1, str2); x != out {
t.Errorf("IndexOfDifference(%v, %v) = %v, want %v", str1, str2, x, out)
}
}
// ****************************** EXAMPLES ********************************************
func ExampleAbbreviate() {
str := "abcdefg"
out1, _ := Abbreviate(str, 6)
out2, _ := Abbreviate(str, 7)
out3, _ := Abbreviate(str, 8)
out4, _ := Abbreviate(str, 4)
_, err1 := Abbreviate(str, 3)
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
fmt.Println(err1)
// Output:
// abc...
// abcdefg
// abcdefg
// a...
// stringutils illegal argument: Minimum abbreviation width is 4
}
func ExampleAbbreviateFull() {
str := "abcdefghijklmno"
str2 := "abcdefghij"
out1, _ := AbbreviateFull(str, -1, 10)
out2, _ := AbbreviateFull(str, 0, 10)
out3, _ := AbbreviateFull(str, 1, 10)
out4, _ := AbbreviateFull(str, 4, 10)
out5, _ := AbbreviateFull(str, 5, 10)
out6, _ := AbbreviateFull(str, 6, 10)
out7, _ := AbbreviateFull(str, 8, 10)
out8, _ := AbbreviateFull(str, 10, 10)
out9, _ := AbbreviateFull(str, 12, 10)
_, err1 := AbbreviateFull(str2, 0, 3)
_, err2 := AbbreviateFull(str2, 5, 6)
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
fmt.Println(out5)
fmt.Println(out6)
fmt.Println(out7)
fmt.Println(out8)
fmt.Println(out9)
fmt.Println(err1)
fmt.Println(err2)
// Output:
// abcdefg...
// abcdefg...
// abcdefg...
// abcdefg...
// ...fghi...
// ...ghij...
// ...ijklmno
// ...ijklmno
// ...ijklmno
// stringutils illegal argument: Minimum abbreviation width is 4
// stringutils illegal argument: Minimum abbreviation width with offset is 7
}
func ExampleIsBlank() {
out1 := IsBlank("")
out2 := IsBlank(" ")
out3 := IsBlank("bob")
out4 := IsBlank(" bob ")
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
// Output:
// true
// true
// false
// false
}
func ExampleDeleteWhiteSpace() {
out1 := DeleteWhiteSpace(" ")
out2 := DeleteWhiteSpace("bob")
out3 := DeleteWhiteSpace("bob ")
out4 := DeleteWhiteSpace(" b o b ")
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
// Output:
//
// bob
// bob
// bob
}
func ExampleIndexOf() {
str := "abcdefgehije"
out1 := IndexOf(str, "e", 0)
out2 := IndexOf(str, "e", 5)
out3 := IndexOf(str, "e", 8)
out4 := IndexOf(str, "eh", 0)
out5 := IndexOf(str, "eh", 22)
out6 := IndexOf(str, "z", 0)
out7 := IndexOf(str, "", 0)
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
fmt.Println(out5)
fmt.Println(out6)
fmt.Println(out7)
// Output:
// 4
// 7
// 11
// 7
// -1
// -1
// -1
}
func ExampleIndexOfDifference() {
out1 := IndexOfDifference("abc", "abc")
out2 := IndexOfDifference("ab", "abxyz")
out3 := IndexOfDifference("", "abc")
out4 := IndexOfDifference("abcde", "abxyz")
fmt.Println(out1)
fmt.Println(out2)
fmt.Println(out3)
fmt.Println(out4)
// Output:
// -1
// 2
// 0
// 2
}

365
vendor/github.com/aokoli/goutils/wordutils.go generated vendored Normal file
View File

@@ -0,0 +1,365 @@
/*
Copyright 2014 Alexander Okoli
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Package goutils provides utility functions to manipulate strings in various ways.
The code snippets below show examples of how to use goutils. Some functions return
errors while others do not, so usage would vary as a result.
Example:
package main
import (
"fmt"
"github.com/aokoli/goutils"
)
func main() {
// EXAMPLE 1: A goutils function which returns no errors
fmt.Println (goutils.Initials("John Doe Foo")) // Prints out "JDF"
// EXAMPLE 2: A goutils function which returns an error
rand1, err1 := goutils.Random (-1, 0, 0, true, true)
if err1 != nil {
fmt.Println(err1) // Prints out error message because -1 was entered as the first parameter in goutils.Random(...)
} else {
fmt.Println(rand1)
}
}
*/
package goutils
import (
"bytes"
"strings"
"unicode"
)
// VERSION indicates the current version of goutils
const VERSION = "1.0.0"
/*
Wrap wraps a single line of text, identifying words by ' '.
New lines will be separated by '\n'. Very long words, such as URLs will not be wrapped.
Leading spaces on a new line are stripped. Trailing spaces are not stripped.
Parameters:
str - the string to be word wrapped
wrapLength - the column (a column can fit only one character) to wrap the words at, less than 1 is treated as 1
Returns:
a line with newlines inserted
*/
func Wrap (str string, wrapLength int) string {
return WrapCustom (str, wrapLength, "", false)
}
/*
WrapCustom wraps a single line of text, identifying words by ' '.
Leading spaces on a new line are stripped. Trailing spaces are not stripped.
Parameters:
str - the string to be word wrapped
wrapLength - the column number (a column can fit only one character) to wrap the words at, less than 1 is treated as 1
newLineStr - the string to insert for a new line, "" uses '\n'
wrapLongWords - true if long words (such as URLs) should be wrapped
Returns:
a line with newlines inserted
*/
func WrapCustom (str string, wrapLength int, newLineStr string, wrapLongWords bool) string {
if str == "" {
return ""
}
if newLineStr == "" {
newLineStr = "\n" // TODO Assumes "\n" is seperator. Explore SystemUtils.LINE_SEPARATOR from Apache Commons
}
if wrapLength < 1 {
wrapLength = 1
}
inputLineLength := len(str)
offset := 0
var wrappedLine bytes.Buffer
for inputLineLength-offset > wrapLength {
if rune(str[offset]) == ' ' {
offset++
continue
}
end := wrapLength + offset + 1
spaceToWrapAt := strings.LastIndex(str[offset:end], " ") + offset
if spaceToWrapAt >= offset {
// normal word (not longer than wrapLength)
wrappedLine.WriteString(str[offset:spaceToWrapAt])
wrappedLine.WriteString(newLineStr)
offset = spaceToWrapAt + 1
} else {
// long word or URL
if wrapLongWords {
end := wrapLength + offset
// long words are wrapped one line at a time
wrappedLine.WriteString(str[offset:end])
wrappedLine.WriteString(newLineStr)
offset += wrapLength
} else {
// long words aren't wrapped, just extended beyond limit
end := wrapLength + offset
spaceToWrapAt = strings.IndexRune(str[end:len(str)], ' ') + end
if spaceToWrapAt >= 0 {
wrappedLine.WriteString(str[offset:spaceToWrapAt])
wrappedLine.WriteString(newLineStr)
offset = spaceToWrapAt + 1
} else {
wrappedLine.WriteString(str[offset:len(str)])
offset = inputLineLength
}
}
}
}
wrappedLine.WriteString(str[offset:len(str)])
return wrappedLine.String()
}
/*
Capitalize capitalizes all the delimiter separated words in a string. Only the first letter of each word is changed.
To convert the rest of each word to lowercase at the same time, use CapitalizeFully(str string, delimiters ...rune).
The delimiters represent a set of characters understood to separate words. The first string character
and the first non-delimiter character after a delimiter will be capitalized. A "" input string returns "".
Capitalization uses the Unicode title case, normally equivalent to upper case.
Parameters:
str - the string to capitalize
delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
Returns:
capitalized string
*/
func Capitalize (str string, delimiters ...rune) string {
var delimLen int
if delimiters == nil {
delimLen = -1
} else {
delimLen = len(delimiters)
}
if str == "" || delimLen == 0 {
return str;
}
buffer := []rune(str)
capitalizeNext := true
for i := 0; i < len(buffer); i++ {
ch := buffer[i]
if isDelimiter(ch, delimiters...) {
capitalizeNext = true
} else if capitalizeNext {
buffer[i] = unicode.ToTitle(ch)
capitalizeNext = false
}
}
return string(buffer)
}
/*
CapitalizeFully converts all the delimiter separated words in a string into capitalized words, that is each word is made up of a
titlecase character and then a series of lowercase characters. The delimiters represent a set of characters understood
to separate words. The first string character and the first non-delimiter character after a delimiter will be capitalized.
Capitalization uses the Unicode title case, normally equivalent to upper case.
Parameters:
str - the string to capitalize fully
delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
Returns:
capitalized string
*/
func CapitalizeFully (str string, delimiters ...rune) string {
var delimLen int
if delimiters == nil {
delimLen = -1
} else {
delimLen = len(delimiters)
}
if str == "" || delimLen == 0 {
return str;
}
str = strings.ToLower(str)
return Capitalize(str, delimiters...);
}
/*
Uncapitalize uncapitalizes all the whitespace separated words in a string. Only the first letter of each word is changed.
The delimiters represent a set of characters understood to separate words. The first string character and the first non-delimiter
character after a delimiter will be uncapitalized. Whitespace is defined by unicode.IsSpace(char).
Parameters:
str - the string to uncapitalize fully
delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
Returns:
uncapitalized string
*/
func Uncapitalize (str string, delimiters ...rune) string {
var delimLen int
if delimiters == nil {
delimLen = -1
} else {
delimLen = len(delimiters)
}
if str == "" || delimLen == 0 {
return str;
}
buffer := []rune(str)
uncapitalizeNext := true // TODO Always makes capitalize/un apply to first char.
for i := 0; i < len(buffer); i++ {
ch := buffer[i]
if isDelimiter(ch, delimiters...) {
uncapitalizeNext = true
} else if uncapitalizeNext {
buffer[i] = unicode.ToLower(ch)
uncapitalizeNext = false
}
}
return string(buffer)
}
/*
SwapCase swaps the case of a string using a word based algorithm.
Conversion algorithm:
Upper case character converts to Lower case
Title case character converts to Lower case
Lower case character after Whitespace or at start converts to Title case
Other Lower case character converts to Upper case
Whitespace is defined by unicode.IsSpace(char).
Parameters:
str - the string to swap case
Returns:
the changed string
*/
func SwapCase(str string) string {
if str == "" {
return str
}
buffer := []rune(str)
whitespace := true
for i := 0; i < len(buffer); i++ {
ch := buffer[i]
if unicode.IsUpper(ch) {
buffer[i] = unicode.ToLower(ch)
whitespace = false
} else if unicode.IsTitle(ch) {
buffer[i] = unicode.ToLower(ch)
whitespace = false
} else if unicode.IsLower(ch) {
if whitespace {
buffer[i] = unicode.ToTitle(ch)
whitespace = false
} else {
buffer[i] = unicode.ToUpper(ch)
}
} else {
whitespace = unicode.IsSpace(ch)
}
}
return string(buffer);
}
/*
Initials extracts the initial letters from each word in the string. The first letter of the string and all first
letters after the defined delimiters are returned as a new string. Their case is not changed. If the delimiters
parameter is excluded, then Whitespace is used. Whitespace is defined by unicode.IsSpacea(char). An empty delimiter array returns an empty string.
Parameters:
str - the string to get initials from
delimiters - set of characters to determine words, exclusion of this parameter means whitespace would be delimeter
Returns:
string of initial letters
*/
func Initials(str string, delimiters ...rune) string {
if str == "" {
return str
}
if delimiters != nil && len(delimiters) == 0 {
return ""
}
strLen := len(str)
var buf bytes.Buffer
lastWasGap := true
for i := 0; i < strLen; i++ {
ch := rune(str[i])
if isDelimiter(ch, delimiters...) {
lastWasGap = true
} else if lastWasGap {
buf.WriteRune(ch)
lastWasGap = false
}
}
return buf.String()
}
// private function (lower case func name)
func isDelimiter(ch rune, delimiters ...rune) bool {
if delimiters == nil {
return unicode.IsSpace(ch)
}
for _, delimiter := range delimiters {
if ch == delimiter {
return true
}
}
return false
}

252
vendor/github.com/aokoli/goutils/wordutils_test.go generated vendored Normal file
View File

@@ -0,0 +1,252 @@
package goutils
import (
"testing"
"fmt"
)
// ****************************** TESTS ********************************************
func TestWrapNormalWord(t *testing.T) {
in := "Bob Manuel Bob Manuel"
out := "Bob Manuel\nBob Manuel"
wrapLength := 10
if x := Wrap(in, wrapLength); x != out {
t.Errorf("Wrap(%v) = %v, want %v", in, x, out)
}
}
func TestWrapCustomLongWordFalse(t *testing.T) {
in := "BobManuelBob Bob"
out := "BobManuelBob<br\\>Bob"
wrapLength := 10
newLineStr := "<br\\>"
wrapLongWords := false
if x := WrapCustom(in, wrapLength, newLineStr, wrapLongWords); x != out {
t.Errorf("Wrap(%v) = %v, want %v", in, x, out)
}
}
func TestWrapCustomLongWordTrue(t *testing.T) {
in := "BobManuelBob Bob"
out := "BobManuelB<br\\>ob Bob"
wrapLength := 10
newLineStr := "<br\\>"
wrapLongWords := true
if x := WrapCustom(in, wrapLength, newLineStr, wrapLongWords); x != out {
t.Errorf("WrapCustom(%v) = %v, want %v", in, x, out)
}
}
func TestCapitalize(t *testing.T) {
// Test 1: Checks if function works with 1 parameter, and default whitespace delimiter
in := "test is going.well.thank.you.for inquiring"
out := "Test Is Going.well.thank.you.for Inquiring"
if x := Capitalize(in); x != out {
t.Errorf("Capitalize(%v) = %v, want %v", in, x, out)
}
// Test 2: Checks if function works with both parameters, with param 2 containing whitespace and '.'
out = "Test Is Going.Well.Thank.You.For Inquiring"
delimiters := []rune{' ', '.'}
if x := Capitalize(in, delimiters...); x != out {
t.Errorf("Capitalize(%v) = %v, want %v", in, x, out)
}
}
func TestCapitalizeFully(t *testing.T) {
// Test 1
in := "tEsT iS goiNG.wELL.tHaNk.yOU.for inqUIrING"
out := "Test Is Going.well.thank.you.for Inquiring"
if x := CapitalizeFully(in); x != out {
t.Errorf("CapitalizeFully(%v) = %v, want %v", in, x, out)
}
// Test 2
out = "Test Is Going.Well.Thank.You.For Inquiring"
delimiters := []rune{' ', '.'}
if x := CapitalizeFully(in, delimiters...); x != out {
t.Errorf("CapitalizeFully(%v) = %v, want %v", in, x, out)
}
}
func TestUncapitalize(t *testing.T) {
// Test 1: Checks if function works with 1 parameter, and default whitespace delimiter
in := "This Is A.Test"
out := "this is a.Test"
if x := Uncapitalize(in); x != out {
t.Errorf("Uncapitalize(%v) = %v, want %v", in, x, out)
}
// Test 2: Checks if function works with both parameters, with param 2 containing whitespace and '.'
out = "this is a.test"
delimiters := []rune{' ', '.'}
if x := Uncapitalize(in, delimiters...); x != out {
t.Errorf("Uncapitalize(%v) = %v, want %v", in, x, out)
}
}
func TestSwapCase(t *testing.T) {
in := "This Is A.Test"
out := "tHIS iS a.tEST"
if x := SwapCase(in); x != out {
t.Errorf("SwapCase(%v) = %v, want %v", in, x, out)
}
}
func TestInitials(t *testing.T) {
// Test 1
in := "John Doe.Ray"
out := "JD"
if x := Initials(in); x != out {
t.Errorf("Initials(%v) = %v, want %v", in, x, out)
}
// Test 2
out = "JDR"
delimiters := []rune{' ','.'}
if x := Initials(in, delimiters...); x != out {
t.Errorf("Initials(%v) = %v, want %v", in, x, out)
}
}
// ****************************** EXAMPLES ********************************************
func ExampleWrap() {
in := "Bob Manuel Bob Manuel"
wrapLength := 10
fmt.Println (Wrap(in, wrapLength))
// Output:
// Bob Manuel
// Bob Manuel
}
func ExampleWrapCustom_1() {
in := "BobManuelBob Bob"
wrapLength := 10
newLineStr := "<br\\>"
wrapLongWords := false
fmt.Println (WrapCustom(in, wrapLength, newLineStr, wrapLongWords))
// Output:
// BobManuelBob<br\>Bob
}
func ExampleWrapCustom_2() {
in := "BobManuelBob Bob"
wrapLength := 10
newLineStr := "<br\\>"
wrapLongWords := true
fmt.Println (WrapCustom(in, wrapLength, newLineStr, wrapLongWords))
// Output:
// BobManuelB<br\>ob Bob
}
func ExampleCapitalize() {
in := "test is going.well.thank.you.for inquiring" // Compare input to CapitalizeFully example
delimiters := []rune{' ', '.'}
fmt.Println (Capitalize(in))
fmt.Println (Capitalize(in, delimiters...))
// Output:
// Test Is Going.well.thank.you.for Inquiring
// Test Is Going.Well.Thank.You.For Inquiring
}
func ExampleCapitalizeFully() {
in := "tEsT iS goiNG.wELL.tHaNk.yOU.for inqUIrING" // Notice scattered capitalization
delimiters := []rune{' ', '.'}
fmt.Println (CapitalizeFully(in))
fmt.Println (CapitalizeFully(in, delimiters...))
// Output:
// Test Is Going.well.thank.you.for Inquiring
// Test Is Going.Well.Thank.You.For Inquiring
}
func ExampleUncapitalize() {
in := "This Is A.Test"
delimiters := []rune{' ', '.'}
fmt.Println (Uncapitalize(in))
fmt.Println (Uncapitalize(in, delimiters...))
// Output:
// this is a.Test
// this is a.test
}
func ExampleSwapCase() {
in := "This Is A.Test"
fmt.Println (SwapCase(in))
// Output:
// tHIS iS a.tEST
}
func ExampleInitials() {
in := "John Doe.Ray"
delimiters := []rune{' ','.'}
fmt.Println (Initials(in))
fmt.Println (Initials(in, delimiters...))
// Output:
// JD
// JDR
}

View File

@@ -169,6 +169,13 @@ func (m *ConformanceRequest) GetJsonPayload() string {
return ""
}
func (m *ConformanceRequest) GetRequestedOutputFormat() WireFormat {
if m != nil {
return m.RequestedOutputFormat
}
return WireFormat_UNSPECIFIED
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*ConformanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _ConformanceRequest_OneofMarshaler, _ConformanceRequest_OneofUnmarshaler, _ConformanceRequest_OneofSizer, []interface{}{
@@ -571,22 +578,22 @@ type TestAllTypes struct {
// (protobuf says names can be any valid C/C++ identifier.)
Fieldname1 int32 `protobuf:"varint,401,opt,name=fieldname1" json:"fieldname1,omitempty"`
FieldName2 int32 `protobuf:"varint,402,opt,name=field_name2,json=fieldName2" json:"field_name2,omitempty"`
XFieldName3 int32 `protobuf:"varint,403,opt,name=_field_name3,json=fieldName3" json:"_field_name3,omitempty"`
XFieldName3 int32 `protobuf:"varint,403,opt,name=_field_name3,json=FieldName3" json:"_field_name3,omitempty"`
Field_Name4_ int32 `protobuf:"varint,404,opt,name=field__name4_,json=fieldName4" json:"field__name4_,omitempty"`
Field0Name5 int32 `protobuf:"varint,405,opt,name=field0name5" json:"field0name5,omitempty"`
Field_0Name6 int32 `protobuf:"varint,406,opt,name=field_0_name6,json=field0Name6" json:"field_0_name6,omitempty"`
FieldName7 int32 `protobuf:"varint,407,opt,name=fieldName7" json:"fieldName7,omitempty"`
FieldName8 int32 `protobuf:"varint,408,opt,name=FieldName8,json=fieldName8" json:"FieldName8,omitempty"`
FieldName8 int32 `protobuf:"varint,408,opt,name=FieldName8" json:"FieldName8,omitempty"`
Field_Name9 int32 `protobuf:"varint,409,opt,name=field_Name9,json=fieldName9" json:"field_Name9,omitempty"`
Field_Name10 int32 `protobuf:"varint,410,opt,name=Field_Name10,json=fieldName10" json:"Field_Name10,omitempty"`
FIELD_NAME11 int32 `protobuf:"varint,411,opt,name=FIELD_NAME11,json=fIELDNAME11" json:"FIELD_NAME11,omitempty"`
FIELDName12 int32 `protobuf:"varint,412,opt,name=FIELD_name12,json=fIELDName12" json:"FIELD_name12,omitempty"`
XFieldName13 int32 `protobuf:"varint,413,opt,name=__field_name13,json=fieldName13" json:"__field_name13,omitempty"`
X_FieldName14 int32 `protobuf:"varint,414,opt,name=__Field_name14,json=fieldName14" json:"__Field_name14,omitempty"`
Field_Name10 int32 `protobuf:"varint,410,opt,name=Field_Name10,json=FieldName10" json:"Field_Name10,omitempty"`
FIELD_NAME11 int32 `protobuf:"varint,411,opt,name=FIELD_NAME11,json=FIELDNAME11" json:"FIELD_NAME11,omitempty"`
FIELDName12 int32 `protobuf:"varint,412,opt,name=FIELD_name12,json=FIELDName12" json:"FIELD_name12,omitempty"`
XFieldName13 int32 `protobuf:"varint,413,opt,name=__field_name13,json=FieldName13" json:"__field_name13,omitempty"`
X_FieldName14 int32 `protobuf:"varint,414,opt,name=__Field_name14,json=FieldName14" json:"__Field_name14,omitempty"`
Field_Name15 int32 `protobuf:"varint,415,opt,name=field__name15,json=fieldName15" json:"field__name15,omitempty"`
Field__Name16 int32 `protobuf:"varint,416,opt,name=field__Name16,json=fieldName16" json:"field__Name16,omitempty"`
FieldName17__ int32 `protobuf:"varint,417,opt,name=field_name17__,json=fieldName17" json:"field_name17__,omitempty"`
FieldName18__ int32 `protobuf:"varint,418,opt,name=Field_name18__,json=fieldName18" json:"Field_name18__,omitempty"`
FieldName18__ int32 `protobuf:"varint,418,opt,name=Field_name18__,json=FieldName18" json:"Field_name18__,omitempty"`
}
func (m *TestAllTypes) Reset() { *m = TestAllTypes{} }
@@ -643,6 +650,111 @@ func (m *TestAllTypes) GetOneofField() isTestAllTypes_OneofField {
return nil
}
func (m *TestAllTypes) GetOptionalInt32() int32 {
if m != nil {
return m.OptionalInt32
}
return 0
}
func (m *TestAllTypes) GetOptionalInt64() int64 {
if m != nil {
return m.OptionalInt64
}
return 0
}
func (m *TestAllTypes) GetOptionalUint32() uint32 {
if m != nil {
return m.OptionalUint32
}
return 0
}
func (m *TestAllTypes) GetOptionalUint64() uint64 {
if m != nil {
return m.OptionalUint64
}
return 0
}
func (m *TestAllTypes) GetOptionalSint32() int32 {
if m != nil {
return m.OptionalSint32
}
return 0
}
func (m *TestAllTypes) GetOptionalSint64() int64 {
if m != nil {
return m.OptionalSint64
}
return 0
}
func (m *TestAllTypes) GetOptionalFixed32() uint32 {
if m != nil {
return m.OptionalFixed32
}
return 0
}
func (m *TestAllTypes) GetOptionalFixed64() uint64 {
if m != nil {
return m.OptionalFixed64
}
return 0
}
func (m *TestAllTypes) GetOptionalSfixed32() int32 {
if m != nil {
return m.OptionalSfixed32
}
return 0
}
func (m *TestAllTypes) GetOptionalSfixed64() int64 {
if m != nil {
return m.OptionalSfixed64
}
return 0
}
func (m *TestAllTypes) GetOptionalFloat() float32 {
if m != nil {
return m.OptionalFloat
}
return 0
}
func (m *TestAllTypes) GetOptionalDouble() float64 {
if m != nil {
return m.OptionalDouble
}
return 0
}
func (m *TestAllTypes) GetOptionalBool() bool {
if m != nil {
return m.OptionalBool
}
return false
}
func (m *TestAllTypes) GetOptionalString() string {
if m != nil {
return m.OptionalString
}
return ""
}
func (m *TestAllTypes) GetOptionalBytes() []byte {
if m != nil {
return m.OptionalBytes
}
return nil
}
func (m *TestAllTypes) GetOptionalNestedMessage() *TestAllTypes_NestedMessage {
if m != nil {
return m.OptionalNestedMessage
@@ -657,6 +769,34 @@ func (m *TestAllTypes) GetOptionalForeignMessage() *ForeignMessage {
return nil
}
func (m *TestAllTypes) GetOptionalNestedEnum() TestAllTypes_NestedEnum {
if m != nil {
return m.OptionalNestedEnum
}
return TestAllTypes_FOO
}
func (m *TestAllTypes) GetOptionalForeignEnum() ForeignEnum {
if m != nil {
return m.OptionalForeignEnum
}
return ForeignEnum_FOREIGN_FOO
}
func (m *TestAllTypes) GetOptionalStringPiece() string {
if m != nil {
return m.OptionalStringPiece
}
return ""
}
func (m *TestAllTypes) GetOptionalCord() string {
if m != nil {
return m.OptionalCord
}
return ""
}
func (m *TestAllTypes) GetRecursiveMessage() *TestAllTypes {
if m != nil {
return m.RecursiveMessage
@@ -664,6 +804,111 @@ func (m *TestAllTypes) GetRecursiveMessage() *TestAllTypes {
return nil
}
func (m *TestAllTypes) GetRepeatedInt32() []int32 {
if m != nil {
return m.RepeatedInt32
}
return nil
}
func (m *TestAllTypes) GetRepeatedInt64() []int64 {
if m != nil {
return m.RepeatedInt64
}
return nil
}
func (m *TestAllTypes) GetRepeatedUint32() []uint32 {
if m != nil {
return m.RepeatedUint32
}
return nil
}
func (m *TestAllTypes) GetRepeatedUint64() []uint64 {
if m != nil {
return m.RepeatedUint64
}
return nil
}
func (m *TestAllTypes) GetRepeatedSint32() []int32 {
if m != nil {
return m.RepeatedSint32
}
return nil
}
func (m *TestAllTypes) GetRepeatedSint64() []int64 {
if m != nil {
return m.RepeatedSint64
}
return nil
}
func (m *TestAllTypes) GetRepeatedFixed32() []uint32 {
if m != nil {
return m.RepeatedFixed32
}
return nil
}
func (m *TestAllTypes) GetRepeatedFixed64() []uint64 {
if m != nil {
return m.RepeatedFixed64
}
return nil
}
func (m *TestAllTypes) GetRepeatedSfixed32() []int32 {
if m != nil {
return m.RepeatedSfixed32
}
return nil
}
func (m *TestAllTypes) GetRepeatedSfixed64() []int64 {
if m != nil {
return m.RepeatedSfixed64
}
return nil
}
func (m *TestAllTypes) GetRepeatedFloat() []float32 {
if m != nil {
return m.RepeatedFloat
}
return nil
}
func (m *TestAllTypes) GetRepeatedDouble() []float64 {
if m != nil {
return m.RepeatedDouble
}
return nil
}
func (m *TestAllTypes) GetRepeatedBool() []bool {
if m != nil {
return m.RepeatedBool
}
return nil
}
func (m *TestAllTypes) GetRepeatedString() []string {
if m != nil {
return m.RepeatedString
}
return nil
}
func (m *TestAllTypes) GetRepeatedBytes() [][]byte {
if m != nil {
return m.RepeatedBytes
}
return nil
}
func (m *TestAllTypes) GetRepeatedNestedMessage() []*TestAllTypes_NestedMessage {
if m != nil {
return m.RepeatedNestedMessage
@@ -678,6 +923,34 @@ func (m *TestAllTypes) GetRepeatedForeignMessage() []*ForeignMessage {
return nil
}
func (m *TestAllTypes) GetRepeatedNestedEnum() []TestAllTypes_NestedEnum {
if m != nil {
return m.RepeatedNestedEnum
}
return nil
}
func (m *TestAllTypes) GetRepeatedForeignEnum() []ForeignEnum {
if m != nil {
return m.RepeatedForeignEnum
}
return nil
}
func (m *TestAllTypes) GetRepeatedStringPiece() []string {
if m != nil {
return m.RepeatedStringPiece
}
return nil
}
func (m *TestAllTypes) GetRepeatedCord() []string {
if m != nil {
return m.RepeatedCord
}
return nil
}
func (m *TestAllTypes) GetMapInt32Int32() map[int32]int32 {
if m != nil {
return m.MapInt32Int32
@@ -1084,6 +1357,132 @@ func (m *TestAllTypes) GetRepeatedValue() []*google_protobuf3.Value {
return nil
}
func (m *TestAllTypes) GetFieldname1() int32 {
if m != nil {
return m.Fieldname1
}
return 0
}
func (m *TestAllTypes) GetFieldName2() int32 {
if m != nil {
return m.FieldName2
}
return 0
}
func (m *TestAllTypes) GetXFieldName3() int32 {
if m != nil {
return m.XFieldName3
}
return 0
}
func (m *TestAllTypes) GetField_Name4_() int32 {
if m != nil {
return m.Field_Name4_
}
return 0
}
func (m *TestAllTypes) GetField0Name5() int32 {
if m != nil {
return m.Field0Name5
}
return 0
}
func (m *TestAllTypes) GetField_0Name6() int32 {
if m != nil {
return m.Field_0Name6
}
return 0
}
func (m *TestAllTypes) GetFieldName7() int32 {
if m != nil {
return m.FieldName7
}
return 0
}
func (m *TestAllTypes) GetFieldName8() int32 {
if m != nil {
return m.FieldName8
}
return 0
}
func (m *TestAllTypes) GetField_Name9() int32 {
if m != nil {
return m.Field_Name9
}
return 0
}
func (m *TestAllTypes) GetField_Name10() int32 {
if m != nil {
return m.Field_Name10
}
return 0
}
func (m *TestAllTypes) GetFIELD_NAME11() int32 {
if m != nil {
return m.FIELD_NAME11
}
return 0
}
func (m *TestAllTypes) GetFIELDName12() int32 {
if m != nil {
return m.FIELDName12
}
return 0
}
func (m *TestAllTypes) GetXFieldName13() int32 {
if m != nil {
return m.XFieldName13
}
return 0
}
func (m *TestAllTypes) GetX_FieldName14() int32 {
if m != nil {
return m.X_FieldName14
}
return 0
}
func (m *TestAllTypes) GetField_Name15() int32 {
if m != nil {
return m.Field_Name15
}
return 0
}
func (m *TestAllTypes) GetField__Name16() int32 {
if m != nil {
return m.Field__Name16
}
return 0
}
func (m *TestAllTypes) GetFieldName17__() int32 {
if m != nil {
return m.FieldName17__
}
return 0
}
func (m *TestAllTypes) GetFieldName18__() int32 {
if m != nil {
return m.FieldName18__
}
return 0
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*TestAllTypes) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _TestAllTypes_OneofMarshaler, _TestAllTypes_OneofUnmarshaler, _TestAllTypes_OneofSizer, []interface{}{
@@ -1267,6 +1666,13 @@ func (m *TestAllTypes_NestedMessage) String() string { return proto.C
func (*TestAllTypes_NestedMessage) ProtoMessage() {}
func (*TestAllTypes_NestedMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} }
func (m *TestAllTypes_NestedMessage) GetA() int32 {
if m != nil {
return m.A
}
return 0
}
func (m *TestAllTypes_NestedMessage) GetCorecursive() *TestAllTypes {
if m != nil {
return m.Corecursive
@@ -1283,6 +1689,13 @@ func (m *ForeignMessage) String() string { return proto.CompactTextSt
func (*ForeignMessage) ProtoMessage() {}
func (*ForeignMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *ForeignMessage) GetC() int32 {
if m != nil {
return m.C
}
return 0
}
func init() {
proto.RegisterType((*ConformanceRequest)(nil), "conformance.ConformanceRequest")
proto.RegisterType((*ConformanceResponse)(nil), "conformance.ConformanceResponse")
@@ -1297,176 +1710,177 @@ func init() {
func init() { proto.RegisterFile("conformance_proto/conformance.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 2731 bytes of a gzipped FileDescriptorProto
// 2737 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x5a, 0xd9, 0x72, 0xdb, 0xc8,
0xd5, 0x16, 0x08, 0x59, 0x4b, 0x93, 0x92, 0xa8, 0xd6, 0xd6, 0x96, 0x5d, 0x63, 0x58, 0xb2, 0x7f,
0xd3, 0xf6, 0x8c, 0x6c, 0x49, 0x30, 0x2c, 0x7b, 0xfe, 0x71, 0x2c, 0xda, 0xa4, 0x25, 0x67, 0x2c,
0xb9, 0x20, 0x6b, 0x5c, 0xe5, 0x5c, 0x30, 0x10, 0x05, 0xa9, 0x38, 0x26, 0x09, 0x0e, 0x40, 0x7a,
0xa2, 0x5c, 0xe6, 0x0d, 0xb2, 0xef, 0xeb, 0x7d, 0xd6, 0x9b, 0x24, 0x95, 0x5c, 0xa5, 0x72, 0x93,
0x3d, 0xa9, 0xec, 0xc9, 0x2b, 0xe4, 0x1d, 0x92, 0xea, 0x15, 0xdd, 0x0d, 0x80, 0xa2, 0xa7, 0x6a,
0x28, 0xf1, 0xe0, 0xeb, 0xef, 0x9c, 0x3e, 0xe7, 0xe0, 0x6b, 0xe1, 0xc0, 0x60, 0xb9, 0x1e, 0xb4,
0x8f, 0x82, 0xb0, 0xe5, 0xb5, 0xeb, 0x7e, 0xad, 0x13, 0x06, 0xdd, 0xe0, 0x86, 0x64, 0x59, 0x21,
0x16, 0x98, 0x97, 0x4c, 0x8b, 0x67, 0x8f, 0x83, 0xe0, 0xb8, 0xe9, 0xdf, 0x20, 0x97, 0x0e, 0x7a,
0x47, 0x37, 0xbc, 0xf6, 0x09, 0xc5, 0x2d, 0xbe, 0xa1, 0x5f, 0x3a, 0xec, 0x85, 0x5e, 0xb7, 0x11,
0xb4, 0xd9, 0x75, 0x4b, 0xbf, 0x7e, 0xd4, 0xf0, 0x9b, 0x87, 0xb5, 0x96, 0x17, 0xbd, 0x64, 0x88,
0xf3, 0x3a, 0x22, 0xea, 0x86, 0xbd, 0x7a, 0x97, 0x5d, 0xbd, 0xa0, 0x5f, 0xed, 0x36, 0x5a, 0x7e,
0xd4, 0xf5, 0x5a, 0x9d, 0xac, 0x00, 0x3e, 0x0c, 0xbd, 0x4e, 0xc7, 0x0f, 0x23, 0x7a, 0x7d, 0xe9,
0x17, 0x06, 0x80, 0x0f, 0xe2, 0xbd, 0xb8, 0xfe, 0x07, 0x3d, 0x3f, 0xea, 0xc2, 0xeb, 0xa0, 0xc8,
0x57, 0xd4, 0x3a, 0xde, 0x49, 0x33, 0xf0, 0x0e, 0x91, 0x61, 0x19, 0xa5, 0xc2, 0xd6, 0x90, 0x3b,
0xc5, 0xaf, 0x3c, 0xa5, 0x17, 0xe0, 0x32, 0x28, 0xbc, 0x1f, 0x05, 0x6d, 0x01, 0xcc, 0x59, 0x46,
0x69, 0x7c, 0x6b, 0xc8, 0xcd, 0x63, 0x2b, 0x07, 0xed, 0x82, 0x85, 0x90, 0x92, 0xfb, 0x87, 0xb5,
0xa0, 0xd7, 0xed, 0xf4, 0xba, 0x35, 0xe2, 0xb5, 0x8b, 0x4c, 0xcb, 0x28, 0x4d, 0xae, 0x2d, 0xac,
0xc8, 0x69, 0x7e, 0xde, 0x08, 0xfd, 0x2a, 0xb9, 0xec, 0xce, 0x89, 0x75, 0xbb, 0x64, 0x19, 0x35,
0x97, 0xc7, 0xc1, 0x28, 0x73, 0xb8, 0xf4, 0xa9, 0x1c, 0x98, 0x51, 0x36, 0x11, 0x75, 0x82, 0x76,
0xe4, 0xc3, 0x8b, 0x20, 0xdf, 0xf1, 0xc2, 0xc8, 0xaf, 0xf9, 0x61, 0x18, 0x84, 0x64, 0x03, 0x38,
0x2e, 0x40, 0x8c, 0x15, 0x6c, 0x83, 0x57, 0xc1, 0x54, 0xe4, 0x87, 0x0d, 0xaf, 0xd9, 0xf8, 0x24,
0x87, 0x8d, 0x30, 0xd8, 0xa4, 0xb8, 0x40, 0xa1, 0x97, 0xc1, 0x44, 0xd8, 0x6b, 0xe3, 0x04, 0x33,
0x20, 0xdf, 0x67, 0x81, 0x99, 0x29, 0x2c, 0x2d, 0x75, 0xe6, 0xa0, 0xa9, 0x1b, 0x4e, 0x4b, 0xdd,
0x22, 0x18, 0x8d, 0x5e, 0x36, 0x3a, 0x1d, 0xff, 0x10, 0x9d, 0x61, 0xd7, 0xb9, 0xa1, 0x3c, 0x06,
0x46, 0x42, 0x3f, 0xea, 0x35, 0xbb, 0x4b, 0xff, 0xa9, 0x82, 0xc2, 0x33, 0x3f, 0xea, 0x6e, 0x36,
0x9b, 0xcf, 0x4e, 0x3a, 0x7e, 0x04, 0x2f, 0x83, 0xc9, 0xa0, 0x83, 0x7b, 0xcd, 0x6b, 0xd6, 0x1a,
0xed, 0xee, 0xfa, 0x1a, 0x49, 0xc0, 0x19, 0x77, 0x82, 0x5b, 0xb7, 0xb1, 0x51, 0x87, 0x39, 0x36,
0xd9, 0x97, 0xa9, 0xc0, 0x1c, 0x1b, 0x5e, 0x01, 0x53, 0x02, 0xd6, 0xa3, 0x74, 0x78, 0x57, 0x13,
0xae, 0x58, 0xbd, 0x4f, 0xac, 0x09, 0xa0, 0x63, 0x93, 0x5d, 0x0d, 0xab, 0x40, 0x8d, 0x31, 0xa2,
0x8c, 0x78, 0x7b, 0xd3, 0x31, 0x70, 0x2f, 0xc9, 0x18, 0x51, 0x46, 0x5c, 0x23, 0xa8, 0x02, 0x1d,
0x1b, 0x5e, 0x05, 0x45, 0x01, 0x3c, 0x6a, 0x7c, 0xc2, 0x3f, 0x5c, 0x5f, 0x43, 0xa3, 0x96, 0x51,
0x1a, 0x75, 0x05, 0x41, 0x95, 0x9a, 0x93, 0x50, 0xc7, 0x46, 0x63, 0x96, 0x51, 0x1a, 0xd1, 0xa0,
0x8e, 0x0d, 0xaf, 0x83, 0xe9, 0xd8, 0x3d, 0xa7, 0x1d, 0xb7, 0x8c, 0xd2, 0x94, 0x2b, 0x38, 0xf6,
0x98, 0x3d, 0x05, 0xec, 0xd8, 0x08, 0x58, 0x46, 0xa9, 0xa8, 0x83, 0x1d, 0x5b, 0x49, 0xfd, 0x51,
0x33, 0xf0, 0xba, 0x28, 0x6f, 0x19, 0xa5, 0x5c, 0x9c, 0xfa, 0x2a, 0x36, 0x2a, 0xfb, 0x3f, 0x0c,
0x7a, 0x07, 0x4d, 0x1f, 0x15, 0x2c, 0xa3, 0x64, 0xc4, 0xfb, 0x7f, 0x48, 0xac, 0x70, 0x19, 0x88,
0x95, 0xb5, 0x83, 0x20, 0x68, 0xa2, 0x09, 0xcb, 0x28, 0x8d, 0xb9, 0x05, 0x6e, 0x2c, 0x07, 0x41,
0xd3, 0xf6, 0x8c, 0xac, 0x05, 0x86, 0x65, 0xcf, 0x3f, 0x8e, 0x45, 0x9b, 0xb4, 0xe4, 0x8c, 0x25,
0x17, 0x64, 0x8d, 0xab, 0x9c, 0x0b, 0x06, 0xa6, 0x20, 0x15, 0xc7, 0x24, 0xc1, 0x01, 0x48, 0x4f,
0x94, 0xcb, 0xbc, 0x41, 0xf6, 0x7d, 0xbd, 0xcf, 0x7a, 0x93, 0xa4, 0x92, 0xab, 0x54, 0x6e, 0xb2,
0x27, 0x95, 0x3d, 0x79, 0x85, 0xbc, 0x43, 0x52, 0xbd, 0xa2, 0xbb, 0x01, 0x50, 0xf4, 0x54, 0x0d,
0x25, 0x1e, 0x7c, 0xfd, 0x9d, 0xd3, 0xe7, 0x1c, 0x7c, 0x2d, 0x1c, 0x18, 0x2c, 0xd7, 0x83, 0xf6,
0x51, 0x10, 0xb6, 0xbc, 0x76, 0xdd, 0xaf, 0x75, 0xc2, 0xa0, 0x1b, 0xdc, 0x90, 0x2c, 0x2b, 0xc4,
0x02, 0xf3, 0x92, 0x69, 0xf1, 0xec, 0x71, 0x10, 0x1c, 0x37, 0xfd, 0x1b, 0xe4, 0xd2, 0x8b, 0xde,
0xd1, 0x0d, 0xaf, 0x7d, 0x42, 0x71, 0x8b, 0x6f, 0xe8, 0x97, 0x0e, 0x7b, 0xa1, 0xd7, 0x6d, 0x04,
0x6d, 0x76, 0xdd, 0xd2, 0xaf, 0x1f, 0x35, 0xfc, 0xe6, 0x61, 0xad, 0xe5, 0x45, 0x2f, 0x19, 0xe2,
0xbc, 0x8e, 0x88, 0xba, 0x61, 0xaf, 0xde, 0x65, 0x57, 0x2f, 0xe8, 0x57, 0xbb, 0x8d, 0x96, 0x1f,
0x75, 0xbd, 0x56, 0x27, 0x2b, 0x80, 0x0f, 0x43, 0xaf, 0xd3, 0xf1, 0xc3, 0x88, 0x5e, 0x5f, 0xfa,
0x85, 0x01, 0xe0, 0xfd, 0x78, 0x2f, 0xae, 0xff, 0x41, 0xcf, 0x8f, 0xba, 0xf0, 0x3a, 0x28, 0xf2,
0x15, 0xb5, 0x8e, 0x77, 0xd2, 0x0c, 0xbc, 0x43, 0x64, 0x58, 0x46, 0xa9, 0xb0, 0x3d, 0xe4, 0x4e,
0xf1, 0x2b, 0x4f, 0xe8, 0x05, 0xb8, 0x0c, 0x0a, 0xef, 0x47, 0x41, 0x5b, 0x00, 0x73, 0x96, 0x51,
0x1a, 0xdf, 0x1e, 0x72, 0xf3, 0xd8, 0xca, 0x41, 0x7b, 0x60, 0x21, 0xa4, 0xe4, 0xfe, 0x61, 0x2d,
0xe8, 0x75, 0x3b, 0xbd, 0x6e, 0x8d, 0x78, 0xed, 0x22, 0xd3, 0x32, 0x4a, 0x93, 0xeb, 0x0b, 0x2b,
0x72, 0x9a, 0x9f, 0x35, 0x42, 0xbf, 0x4a, 0x2e, 0xbb, 0x73, 0x62, 0xdd, 0x1e, 0x59, 0x46, 0xcd,
0xe5, 0x71, 0x30, 0xca, 0x1c, 0x2e, 0x7d, 0x2a, 0x07, 0x66, 0x94, 0x4d, 0x44, 0x9d, 0xa0, 0x1d,
0xf9, 0xf0, 0x22, 0xc8, 0x77, 0xbc, 0x30, 0xf2, 0x6b, 0x7e, 0x18, 0x06, 0x21, 0xd9, 0x00, 0x8e,
0x0b, 0x10, 0x63, 0x05, 0xdb, 0xe0, 0x55, 0x30, 0x15, 0xf9, 0x61, 0xc3, 0x6b, 0x36, 0x3e, 0xc9,
0x61, 0x23, 0x0c, 0x36, 0x29, 0x2e, 0x50, 0xe8, 0x65, 0x30, 0x11, 0xf6, 0xda, 0x38, 0xc1, 0x0c,
0xc8, 0xf7, 0x59, 0x60, 0x66, 0x0a, 0x4b, 0x4b, 0x9d, 0x39, 0x68, 0xea, 0x86, 0xd3, 0x52, 0xb7,
0x08, 0x46, 0xa3, 0x97, 0x8d, 0x4e, 0xc7, 0x3f, 0x44, 0x67, 0xd8, 0x75, 0x6e, 0x28, 0x8f, 0x81,
0x91, 0xd0, 0x8f, 0x7a, 0xcd, 0xee, 0xd2, 0x7f, 0xaa, 0xa0, 0xf0, 0xd4, 0x8f, 0xba, 0x5b, 0xcd,
0xe6, 0xd3, 0x93, 0x8e, 0x1f, 0xc1, 0xcb, 0x60, 0x32, 0xe8, 0xe0, 0x5e, 0xf3, 0x9a, 0xb5, 0x46,
0xbb, 0xbb, 0xb1, 0x4e, 0x12, 0x70, 0xc6, 0x9d, 0xe0, 0xd6, 0x1d, 0x6c, 0xd4, 0x61, 0x8e, 0x4d,
0xf6, 0x65, 0x2a, 0x30, 0xc7, 0x86, 0x57, 0xc0, 0x94, 0x80, 0xf5, 0x28, 0x1d, 0xde, 0xd5, 0x84,
0x2b, 0x56, 0x1f, 0x10, 0x6b, 0x02, 0xe8, 0xd8, 0x64, 0x57, 0xc3, 0x2a, 0x50, 0x63, 0x8c, 0x28,
0x23, 0xde, 0xde, 0x74, 0x0c, 0xdc, 0x4f, 0x32, 0x46, 0x94, 0x11, 0xd7, 0x08, 0xaa, 0x40, 0xc7,
0x86, 0x57, 0x41, 0x51, 0x00, 0x8f, 0x1a, 0x9f, 0xf0, 0x0f, 0x37, 0xd6, 0xd1, 0xa8, 0x65, 0x94,
0x46, 0x5d, 0x41, 0x50, 0xa5, 0xe6, 0x24, 0xd4, 0xb1, 0xd1, 0x98, 0x65, 0x94, 0x46, 0x34, 0xa8,
0x63, 0xc3, 0xeb, 0x60, 0x3a, 0x76, 0xcf, 0x69, 0xc7, 0x2d, 0xa3, 0x34, 0xe5, 0x0a, 0x8e, 0x7d,
0x66, 0x4f, 0x01, 0x3b, 0x36, 0x02, 0x96, 0x51, 0x2a, 0xea, 0x60, 0xc7, 0x56, 0x52, 0x7f, 0xd4,
0x0c, 0xbc, 0x2e, 0xca, 0x5b, 0x46, 0x29, 0x17, 0xa7, 0xbe, 0x8a, 0x8d, 0xca, 0xfe, 0x0f, 0x83,
0xde, 0x8b, 0xa6, 0x8f, 0x0a, 0x96, 0x51, 0x32, 0xe2, 0xfd, 0x3f, 0x20, 0x56, 0xb8, 0x0c, 0xc4,
0xca, 0xda, 0x8b, 0x20, 0x68, 0xa2, 0x09, 0xcb, 0x28, 0x8d, 0xb9, 0x05, 0x6e, 0x2c, 0x07, 0x41,
0x53, 0xcd, 0x66, 0x37, 0x6c, 0xb4, 0x8f, 0xd1, 0x24, 0xee, 0x2a, 0x29, 0x9b, 0xc4, 0xaa, 0x44,
0x77, 0x70, 0xd2, 0xf5, 0x23, 0x34, 0x85, 0xdb, 0x38, 0x8e, 0xae, 0x8c, 0x8d, 0xb0, 0x06, 0x16,
0x04, 0xac, 0x4d, 0x6f, 0xef, 0x96, 0x1f, 0x45, 0xde, 0xb1, 0x8f, 0xa0, 0x65, 0x94, 0xf2, 0x6b,
0x57, 0x94, 0x1b, 0x5b, 0x6e, 0xd1, 0x95, 0x1d, 0x82, 0x7f, 0x42, 0xe1, 0xee, 0x1c, 0xe7, 0x51,
0xcc, 0x70, 0x1f, 0xa0, 0x38, 0x4b, 0x41, 0xe8, 0x37, 0x8e, 0xdb, 0xc2, 0xc3, 0x0c, 0xf1, 0x70,
0x4e, 0xf1, 0x50, 0xa5, 0x18, 0xce, 0x3a, 0x2f, 0x92, 0xa9, 0xd8, 0xe1, 0x7b, 0x60, 0x56, 0x8f,
0xdb, 0x6f, 0xf7, 0x5a, 0x68, 0x8e, 0xa8, 0xd1, 0xa5, 0xd3, 0x82, 0xae, 0xb4, 0x7b, 0x2d, 0x17,
0xaa, 0x11, 0x63, 0x1b, 0x7c, 0x17, 0xcc, 0x25, 0xc2, 0x25, 0xc4, 0xf3, 0x84, 0x18, 0xa5, 0xc5,
0x4a, 0xc8, 0x66, 0xb4, 0x40, 0x09, 0x9b, 0x23, 0xb1, 0xd1, 0x6a, 0xd5, 0x3a, 0x0d, 0xbf, 0xee,
0x23, 0x84, 0x6b, 0x56, 0xce, 0x8d, 0xe5, 0xe2, 0x75, 0xb4, 0x6e, 0x4f, 0xf1, 0x65, 0x78, 0x45,
0x6a, 0x85, 0x7a, 0x10, 0x1e, 0xa2, 0xb3, 0x0c, 0x6f, 0xc4, 0xed, 0xf0, 0x20, 0x08, 0x0f, 0x61,
0x15, 0x4c, 0x87, 0x7e, 0xbd, 0x17, 0x46, 0x8d, 0x57, 0xbe, 0x48, 0xeb, 0x39, 0x92, 0xd6, 0xb3,
0x99, 0x39, 0x70, 0x8b, 0x62, 0x0d, 0x4f, 0xe7, 0x65, 0x30, 0x19, 0xfa, 0x1d, 0xdf, 0xc3, 0x79,
0xa4, 0x37, 0xf3, 0x05, 0xcb, 0xc4, 0x6a, 0xc3, 0xad, 0x42, 0x6d, 0x64, 0x98, 0x63, 0x23, 0xcb,
0x32, 0xb1, 0xda, 0x48, 0x30, 0xaa, 0x0d, 0x02, 0xc6, 0xd4, 0xe6, 0xa2, 0x65, 0x62, 0xb5, 0xe1,
0xe6, 0x58, 0x6d, 0x14, 0xa0, 0x63, 0xa3, 0x25, 0xcb, 0xc4, 0x6a, 0x23, 0x03, 0x35, 0x46, 0xa6,
0x36, 0xcb, 0x96, 0x89, 0xd5, 0x86, 0x9b, 0xf7, 0x92, 0x8c, 0x4c, 0x6d, 0x2e, 0x59, 0x26, 0x56,
0x1b, 0x19, 0x48, 0xd5, 0x46, 0x00, 0xb9, 0x2c, 0x5c, 0xb6, 0x4c, 0xac, 0x36, 0xdc, 0x2e, 0xa9,
0x8d, 0x0a, 0x75, 0x6c, 0xf4, 0x7f, 0x96, 0x89, 0xd5, 0x46, 0x81, 0x52, 0xb5, 0x89, 0xdd, 0x73,
0xda, 0x2b, 0x96, 0x89, 0xd5, 0x46, 0x04, 0x20, 0xa9, 0x8d, 0x06, 0x76, 0x6c, 0x54, 0xb2, 0x4c,
0xac, 0x36, 0x2a, 0x98, 0xaa, 0x4d, 0x1c, 0x04, 0x51, 0x9b, 0xab, 0x96, 0x89, 0xd5, 0x46, 0x84,
0xc0, 0xd5, 0x46, 0xc0, 0x98, 0xda, 0x5c, 0xb3, 0x4c, 0xac, 0x36, 0xdc, 0x1c, 0xab, 0x8d, 0x00,
0x12, 0xb5, 0xb9, 0x6e, 0x99, 0x58, 0x6d, 0xb8, 0x91, 0xab, 0x4d, 0x1c, 0x21, 0x55, 0x9b, 0x37,
0x2d, 0x13, 0xab, 0x8d, 0x88, 0x4f, 0xa8, 0x4d, 0xcc, 0x46, 0xd4, 0xe6, 0x2d, 0xcb, 0xc4, 0x6a,
0x23, 0xe8, 0xb8, 0xda, 0x08, 0x98, 0xa6, 0x36, 0x37, 0x2d, 0xf3, 0xb5, 0xd4, 0x86, 0xf3, 0x24,
0xd4, 0x26, 0xce, 0x92, 0xa6, 0x36, 0xab, 0xc4, 0x43, 0x7f, 0xb5, 0x11, 0xc9, 0x4c, 0xa8, 0x8d,
0x1e, 0x37, 0x11, 0x85, 0x75, 0xcb, 0x1c, 0x5c, 0x6d, 0xd4, 0x88, 0xb9, 0xda, 0x24, 0xc2, 0x25,
0xf7, 0xe2, 0xa4, 0xeb, 0x47, 0x68, 0x0a, 0xb7, 0x71, 0x1c, 0x5d, 0x19, 0x1b, 0x61, 0x0d, 0x2c,
0x08, 0x58, 0x9b, 0xde, 0xde, 0x2d, 0x3f, 0x8a, 0xbc, 0x63, 0x1f, 0x41, 0xcb, 0x28, 0xe5, 0xd7,
0xaf, 0x28, 0x37, 0xb6, 0xdc, 0xa2, 0x2b, 0xbb, 0x04, 0xff, 0x98, 0xc2, 0xdd, 0x39, 0xce, 0xa3,
0x98, 0xe1, 0x01, 0x40, 0x71, 0x96, 0x82, 0xd0, 0x6f, 0x1c, 0xb7, 0x85, 0x87, 0x19, 0xe2, 0xe1,
0x9c, 0xe2, 0xa1, 0x4a, 0x31, 0x9c, 0x75, 0x5e, 0x24, 0x53, 0xb1, 0xc3, 0xf7, 0xc0, 0xac, 0x1e,
0xb7, 0xdf, 0xee, 0xb5, 0xd0, 0x1c, 0x51, 0xa3, 0x4b, 0xa7, 0x05, 0x5d, 0x69, 0xf7, 0x5a, 0x2e,
0x54, 0x23, 0xc6, 0x36, 0xf8, 0x2e, 0x98, 0x4b, 0x84, 0x4b, 0x88, 0xe7, 0x09, 0x31, 0x4a, 0x8b,
0x95, 0x90, 0xcd, 0x68, 0x81, 0x12, 0x36, 0x47, 0x62, 0xa3, 0xd5, 0xaa, 0x75, 0x1a, 0x7e, 0xdd,
0x47, 0x08, 0xd7, 0xac, 0x9c, 0x1b, 0xcb, 0xc5, 0xeb, 0x68, 0xdd, 0x9e, 0xe0, 0xcb, 0xf0, 0x8a,
0xd4, 0x0a, 0xf5, 0x20, 0x3c, 0x44, 0x67, 0x19, 0xde, 0x88, 0xdb, 0xe1, 0x7e, 0x10, 0x1e, 0xc2,
0x2a, 0x98, 0x0e, 0xfd, 0x7a, 0x2f, 0x8c, 0x1a, 0xaf, 0x7c, 0x91, 0xd6, 0x73, 0x24, 0xad, 0x67,
0x33, 0x73, 0xe0, 0x16, 0xc5, 0x1a, 0x9e, 0xce, 0xcb, 0x60, 0x32, 0xf4, 0x3b, 0xbe, 0x87, 0xf3,
0x48, 0x6f, 0xe6, 0x0b, 0x96, 0x89, 0xd5, 0x86, 0x5b, 0x85, 0xda, 0xc8, 0x30, 0xc7, 0x46, 0x96,
0x65, 0x62, 0xb5, 0x91, 0x60, 0x54, 0x1b, 0x04, 0x8c, 0xa9, 0xcd, 0x45, 0xcb, 0xc4, 0x6a, 0xc3,
0xcd, 0xb1, 0xda, 0x28, 0x40, 0xc7, 0x46, 0x4b, 0x96, 0x89, 0xd5, 0x46, 0x06, 0x6a, 0x8c, 0x4c,
0x6d, 0x96, 0x2d, 0x13, 0xab, 0x0d, 0x37, 0xef, 0x27, 0x19, 0x99, 0xda, 0x5c, 0xb2, 0x4c, 0xac,
0x36, 0x32, 0x90, 0xaa, 0x8d, 0x00, 0x72, 0x59, 0xb8, 0x6c, 0x99, 0x58, 0x6d, 0xb8, 0x5d, 0x52,
0x1b, 0x15, 0xea, 0xd8, 0xe8, 0xff, 0x2c, 0x13, 0xab, 0x8d, 0x02, 0xa5, 0x6a, 0x13, 0xbb, 0xe7,
0xb4, 0x57, 0x2c, 0x13, 0xab, 0x8d, 0x08, 0x40, 0x52, 0x1b, 0x0d, 0xec, 0xd8, 0xa8, 0x64, 0x99,
0x58, 0x6d, 0x54, 0x30, 0x55, 0x9b, 0x38, 0x08, 0xa2, 0x36, 0x57, 0x2d, 0x13, 0xab, 0x8d, 0x08,
0x81, 0xab, 0x8d, 0x80, 0x31, 0xb5, 0xb9, 0x66, 0x99, 0x58, 0x6d, 0xb8, 0x39, 0x56, 0x1b, 0x01,
0x24, 0x6a, 0x73, 0xdd, 0x32, 0xb1, 0xda, 0x70, 0x23, 0x57, 0x9b, 0x38, 0x42, 0xaa, 0x36, 0x6f,
0x5a, 0x26, 0x56, 0x1b, 0x11, 0x9f, 0x50, 0x9b, 0x98, 0x8d, 0xa8, 0xcd, 0x5b, 0x96, 0x89, 0xd5,
0x46, 0xd0, 0x71, 0xb5, 0x11, 0x30, 0x4d, 0x6d, 0x56, 0x2d, 0xf3, 0xb5, 0xd4, 0x86, 0xf3, 0x24,
0xd4, 0x26, 0xce, 0x92, 0xa6, 0x36, 0x6b, 0xc4, 0x43, 0x7f, 0xb5, 0x11, 0xc9, 0x4c, 0xa8, 0x8d,
0x1e, 0x37, 0x11, 0x85, 0x0d, 0xcb, 0x1c, 0x5c, 0x6d, 0xd4, 0x88, 0xb9, 0xda, 0x24, 0xc2, 0x25,
0xc4, 0x36, 0x21, 0xee, 0xa3, 0x36, 0x5a, 0xa0, 0x5c, 0x6d, 0xb4, 0x6a, 0x31, 0xb5, 0x71, 0x70,
0xcd, 0xa8, 0xda, 0xa8, 0x75, 0x13, 0x6a, 0x23, 0xd6, 0x11, 0xb5, 0xb9, 0xcd, 0xf0, 0x46, 0xdc,
0x0e, 0x44, 0x6d, 0x9e, 0x81, 0xa9, 0x96, 0xd7, 0xa1, 0x02, 0xc1, 0x64, 0x62, 0x83, 0x24, 0xf5,
0xcd, 0xec, 0x0c, 0x3c, 0xf1, 0x3a, 0x44, 0x3b, 0xc8, 0x47, 0xa5, 0xdd, 0x0d, 0x4f, 0xdc, 0x89,
0x96, 0x6c, 0x93, 0x58, 0x1d, 0x9b, 0xa9, 0xca, 0x9d, 0xc1, 0x58, 0x1d, 0x9b, 0x7c, 0x28, 0xac,
0xcc, 0x06, 0x5f, 0x80, 0x69, 0xcc, 0x4a, 0xe5, 0x87, 0xab, 0xd0, 0x5d, 0xc2, 0xbb, 0xd2, 0x97,
0xcd, 0xa8, 0xda, 0xa8, 0x75, 0x13, 0x6a, 0x23, 0xd6, 0x11, 0xb5, 0xb9, 0xc5, 0xf0, 0x46, 0xdc,
0x0e, 0x44, 0x6d, 0x9e, 0x82, 0xa9, 0x96, 0xd7, 0xa1, 0x02, 0xc1, 0x64, 0x62, 0x93, 0x24, 0xf5,
0xcd, 0xec, 0x0c, 0x3c, 0xf6, 0x3a, 0x44, 0x3b, 0xc8, 0x47, 0xa5, 0xdd, 0x0d, 0x4f, 0xdc, 0x89,
0x96, 0x6c, 0x93, 0x58, 0x1d, 0x9b, 0xa9, 0xca, 0xed, 0xc1, 0x58, 0x1d, 0x9b, 0x7c, 0x28, 0xac,
0xcc, 0x06, 0x9f, 0x83, 0x69, 0xcc, 0x4a, 0xe5, 0x87, 0xab, 0xd0, 0x1d, 0xc2, 0xbb, 0xd2, 0x97,
0x97, 0x4a, 0x13, 0xfd, 0xa4, 0xcc, 0x38, 0x3c, 0xd9, 0x2a, 0x73, 0x3b, 0x36, 0x17, 0xae, 0xb7,
0x07, 0xe4, 0x76, 0x6c, 0xfa, 0xa9, 0x72, 0x73, 0x2b, 0xe7, 0xa6, 0x22, 0xc7, 0xb5, 0xee, 0xff,
0x07, 0xe0, 0xa6, 0x02, 0xb8, 0xa7, 0xc5, 0x2d, 0x5b, 0x65, 0x6e, 0xc7, 0xe6, 0xf2, 0xf8, 0xce,
0x80, 0xdc, 0x8e, 0xbd, 0xa7, 0xc5, 0x2d, 0x5b, 0xe1, 0xc7, 0xc1, 0x0c, 0xe6, 0x66, 0xda, 0x26,
0x24, 0xf5, 0x1e, 0x61, 0xbf, 0xd9, 0x97, 0x9d, 0xe9, 0x2c, 0xfb, 0x41, 0xf9, 0x71, 0xa0, 0xaa,
0x5d, 0xf1, 0xe0, 0xd8, 0x42, 0x89, 0x3f, 0x32, 0xa8, 0x07, 0xc7, 0x66, 0x3f, 0x34, 0x0f, 0xc2,
0x0e, 0x8f, 0xc0, 0x1c, 0xc9, 0x0f, 0xdf, 0x84, 0x50, 0xf0, 0xfb, 0xc4, 0xc7, 0x5a, 0xff, 0x1c,
0x31, 0x30, 0xff, 0x49, 0xbd, 0xe0, 0x90, 0xf5, 0x2b, 0xaa, 0x1f, 0x5c, 0x09, 0xbe, 0x97, 0xcd,
0x81, 0xfd, 0x38, 0x36, 0xff, 0xa9, 0xfb, 0x89, 0xaf, 0xa8, 0xf7, 0x2b, 0x3d, 0x34, 0xca, 0x83,
0xde, 0xaf, 0xe4, 0x38, 0xd1, 0xee, 0x57, 0x7a, 0xc4, 0x3c, 0x07, 0xc5, 0x98, 0x95, 0x9d, 0x31,
0x0f, 0x08, 0xed, 0x5b, 0xa7, 0xd3, 0xd2, 0xd3, 0x87, 0xf2, 0x4e, 0xb6, 0x14, 0x23, 0xdc, 0x01,
0xd8, 0x13, 0x39, 0x8d, 0xe8, 0x91, 0xf4, 0x90, 0xb0, 0x5e, 0xeb, 0xcb, 0x8a, 0xcf, 0x29, 0xfc,
0x3f, 0xa5, 0xcc, 0xb7, 0x62, 0x8b, 0x68, 0x77, 0x2a, 0x85, 0xec, 0xfc, 0xaa, 0x0c, 0xd2, 0xee,
0x04, 0x4a, 0x3f, 0xa5, 0x76, 0x97, 0xac, 0x3c, 0x09, 0x8c, 0x9b, 0x1e, 0x79, 0xd5, 0x01, 0x92,
0x40, 0x97, 0x93, 0xd3, 0x30, 0x4e, 0x82, 0x64, 0x84, 0x1d, 0x70, 0x56, 0x22, 0xd6, 0x0e, 0xc9,
0x47, 0xc4, 0xc3, 0xad, 0x01, 0x3c, 0x28, 0xc7, 0x22, 0xf5, 0x34, 0xdf, 0x4a, 0xbd, 0x08, 0x23,
0xb0, 0x28, 0x79, 0xd4, 0x4f, 0xcd, 0x2d, 0xe2, 0xd2, 0x19, 0xc0, 0xa5, 0x7a, 0x66, 0x52, 0x9f,
0x0b, 0xad, 0xf4, 0xab, 0xf0, 0x18, 0xcc, 0x27, 0xb7, 0x49, 0x8e, 0xbe, 0xed, 0x41, 0xee, 0x01,
0x69, 0x1b, 0xf8, 0xe8, 0x93, 0xee, 0x01, 0xed, 0x0a, 0x7c, 0x1f, 0x2c, 0xa4, 0xec, 0x8e, 0x78,
0x7a, 0x4c, 0x3c, 0xad, 0x0f, 0xbe, 0xb5, 0xd8, 0xd5, 0x6c, 0x2b, 0xe5, 0x12, 0x5c, 0x06, 0x85,
0xa0, 0xed, 0x07, 0x47, 0xfc, 0xb8, 0x09, 0xf0, 0x23, 0xf6, 0xd6, 0x90, 0x9b, 0x27, 0x56, 0x76,
0x78, 0x7c, 0x0c, 0xcc, 0x52, 0x90, 0x56, 0xdb, 0xce, 0x6b, 0x3d, 0x6e, 0x6d, 0x0d, 0xb9, 0x90,
0xd0, 0xa8, 0xb5, 0x14, 0x11, 0xb0, 0x6e, 0xff, 0x80, 0x4f, 0x24, 0x88, 0x95, 0xf5, 0xee, 0x45,
0x40, 0xbf, 0xb2, 0xb6, 0x0d, 0xd9, 0x78, 0x03, 0x10, 0x23, 0xed, 0xc2, 0x0b, 0x00, 0x30, 0x08,
0xbe, 0x0f, 0x23, 0xfc, 0x20, 0xba, 0x35, 0xe4, 0x8e, 0x53, 0x04, 0xbe, 0xb7, 0x94, 0xad, 0x3a,
0x36, 0xea, 0x5a, 0x46, 0x69, 0x58, 0xd9, 0xaa, 0x63, 0xc7, 0x8e, 0xa8, 0xf6, 0xf4, 0xf0, 0xe3,
0xb1, 0x70, 0x44, 0xc5, 0x44, 0xf0, 0x30, 0x21, 0x79, 0x85, 0x1f, 0x8d, 0x05, 0x0f, 0x13, 0x86,
0x0a, 0x8f, 0x86, 0x94, 0xed, 0xc3, 0xc1, 0x1f, 0xf1, 0x44, 0xcc, 0xa4, 0x3c, 0xbb, 0xd2, 0xd3,
0x18, 0x11, 0x19, 0x36, 0x4d, 0x43, 0xbf, 0x32, 0x48, 0xee, 0x17, 0x57, 0xe8, 0xb8, 0x6d, 0x85,
0xcf, 0x79, 0x56, 0xf0, 0x56, 0xdf, 0xf3, 0x9a, 0x3d, 0x3f, 0x7e, 0x4c, 0xc3, 0xa6, 0xe7, 0x74,
0x1d, 0x74, 0xc1, 0xbc, 0x3a, 0xa3, 0x11, 0x8c, 0xbf, 0x36, 0xd8, 0xa3, 0xad, 0xce, 0x48, 0xf4,
0x8e, 0x52, 0xce, 0x2a, 0x93, 0x9c, 0x0c, 0x4e, 0xc7, 0x16, 0x9c, 0xbf, 0xe9, 0xc3, 0xe9, 0xd8,
0x49, 0x4e, 0xc7, 0xe6, 0x9c, 0xfb, 0xd2, 0x43, 0x7e, 0x4f, 0x0d, 0xf4, 0xb7, 0x94, 0xf4, 0x7c,
0x82, 0x74, 0x5f, 0x8a, 0x74, 0x4e, 0x1d, 0x12, 0x65, 0xd1, 0x4a, 0xb1, 0xfe, 0xae, 0x1f, 0x2d,
0x0f, 0x76, 0x4e, 0x1d, 0x29, 0xa5, 0x65, 0x80, 0x34, 0x8e, 0x60, 0xfd, 0x7d, 0x56, 0x06, 0x48,
0x2f, 0x69, 0x19, 0x20, 0xb6, 0xb4, 0x50, 0x69, 0xa7, 0x09, 0xd2, 0x3f, 0x64, 0x85, 0x4a, 0x9b,
0x4f, 0x0b, 0x95, 0x1a, 0xd3, 0x68, 0x99, 0xc2, 0x70, 0xda, 0x3f, 0x66, 0xd1, 0xd2, 0x9b, 0x50,
0xa3, 0xa5, 0xc6, 0xb4, 0x0c, 0x90, 0x7b, 0x54, 0xb0, 0xfe, 0x29, 0x2b, 0x03, 0xe4, 0xb6, 0xd5,
0x32, 0x40, 0x6c, 0x9c, 0x73, 0x57, 0x7a, 0x38, 0x50, 0x9a, 0xff, 0xcf, 0x06, 0x91, 0xc1, 0xbe,
0xcd, 0x2f, 0x3f, 0x14, 0x4a, 0x41, 0xaa, 0x23, 0x03, 0xc1, 0xf8, 0x17, 0x83, 0x3d, 0x69, 0xf5,
0x6b, 0x7e, 0x65, 0xb0, 0x90, 0xc1, 0x29, 0x35, 0xd4, 0x5f, 0xfb, 0x70, 0x8a, 0xe6, 0x57, 0xa6,
0x10, 0x52, 0x8d, 0xb4, 0x61, 0x84, 0x20, 0xfd, 0x1b, 0x25, 0x3d, 0xa5, 0xf9, 0xd5, 0x99, 0x45,
0x16, 0xad, 0x14, 0xeb, 0xdf, 0xfb, 0xd1, 0x8a, 0xe6, 0x57, 0x27, 0x1c, 0x69, 0x19, 0x50, 0x9b,
0xff, 0x1f, 0x59, 0x19, 0x90, 0x9b, 0x5f, 0x19, 0x06, 0xa4, 0x85, 0xaa, 0x35, 0xff, 0x3f, 0xb3,
0x42, 0x55, 0x9a, 0x5f, 0x1d, 0x1d, 0xa4, 0xd1, 0x6a, 0xcd, 0xff, 0xaf, 0x2c, 0x5a, 0xa5, 0xf9,
0xd5, 0x67, 0xd1, 0xb4, 0x0c, 0xa8, 0xcd, 0xff, 0xef, 0xac, 0x0c, 0xc8, 0xcd, 0xaf, 0x0c, 0x1c,
0x38, 0xe7, 0x23, 0x69, 0xae, 0xcb, 0xdf, 0xe1, 0xa0, 0xef, 0xe6, 0xd8, 0x9c, 0x2c, 0xb1, 0x77,
0x86, 0x88, 0x67, 0xbe, 0xdc, 0x02, 0x1f, 0x03, 0x31, 0x34, 0xac, 0x89, 0x97, 0x35, 0xe8, 0x7b,
0xb9, 0x8c, 0xf3, 0xe3, 0x19, 0x87, 0xb8, 0xc2, 0xbf, 0x30, 0xc1, 0x8f, 0x82, 0x19, 0x69, 0x88,
0xcd, 0x5f, 0x1c, 0xa1, 0xef, 0x67, 0x91, 0x55, 0x31, 0xe6, 0x89, 0x17, 0xbd, 0x8c, 0xc9, 0x84,
0x09, 0x6e, 0xaa, 0x73, 0xe1, 0x5e, 0xbd, 0x8b, 0x7e, 0x40, 0x89, 0x16, 0xd2, 0x8a, 0xd0, 0xab,
0x77, 0x95, 0x89, 0x71, 0xaf, 0xde, 0x85, 0x1b, 0x40, 0xcc, 0x16, 0x6b, 0x5e, 0xfb, 0x04, 0xfd,
0x90, 0xae, 0x9f, 0x4d, 0xac, 0xdf, 0x6c, 0x9f, 0xb8, 0x79, 0x0e, 0xdd, 0x6c, 0x9f, 0xc0, 0x7b,
0xd2, 0xac, 0xf9, 0x15, 0x2e, 0x03, 0xfa, 0x11, 0x5d, 0x3b, 0x9f, 0x58, 0x4b, 0xab, 0x24, 0xa6,
0x9b, 0xe4, 0x2b, 0x2e, 0x4f, 0xdc, 0xa0, 0xbc, 0x3c, 0x3f, 0xce, 0x91, 0x6a, 0xf7, 0x2b, 0x8f,
0xe8, 0x4b, 0xa9, 0x3c, 0x82, 0x28, 0x2e, 0xcf, 0x4f, 0x72, 0x19, 0x0a, 0x27, 0x95, 0x87, 0x2f,
0x8b, 0xcb, 0x23, 0x73, 0x91, 0xf2, 0x90, 0xea, 0xfc, 0x34, 0x8b, 0x4b, 0xaa, 0x4e, 0x3c, 0x14,
0x64, 0xab, 0x70, 0x75, 0xe4, 0x5b, 0x05, 0x57, 0xe7, 0x97, 0x94, 0x28, 0xbb, 0x3a, 0xd2, 0xdd,
0xc1, 0xaa, 0x23, 0x28, 0x70, 0x75, 0x7e, 0x46, 0xd7, 0x67, 0x54, 0x87, 0x43, 0x59, 0x75, 0xc4,
0x4a, 0x5a, 0x9d, 0x9f, 0xd3, 0xb5, 0x99, 0xd5, 0xe1, 0x70, 0x5a, 0x9d, 0x0b, 0x00, 0x90, 0xfd,
0xb7, 0xbd, 0x96, 0xbf, 0x8a, 0x3e, 0x6d, 0x92, 0xd7, 0x50, 0x92, 0x09, 0x5a, 0x20, 0x4f, 0xfb,
0x17, 0x7f, 0x5d, 0x43, 0x9f, 0x91, 0x11, 0x3b, 0xd8, 0x04, 0x2f, 0x82, 0x42, 0x2d, 0x86, 0xac,
0xa3, 0xcf, 0xea, 0x90, 0x75, 0xb8, 0x04, 0x26, 0x28, 0x82, 0x40, 0xec, 0x1a, 0xfa, 0x9c, 0x8e,
0x21, 0x7f, 0x4f, 0x92, 0x6f, 0x37, 0x31, 0xe4, 0x16, 0xfa, 0x3c, 0x45, 0xc8, 0x36, 0xb8, 0xcc,
0x69, 0x6e, 0x12, 0x1e, 0x07, 0x7d, 0x41, 0x01, 0x61, 0x1e, 0x47, 0xec, 0x08, 0x7f, 0xbb, 0x8d,
0xbe, 0xa8, 0x3b, 0xba, 0x8d, 0x01, 0x55, 0xfe, 0x6d, 0x03, 0x7d, 0x49, 0x07, 0x6c, 0xc4, 0x5b,
0xc6, 0x5f, 0xef, 0xa0, 0x2f, 0xeb, 0x88, 0x3b, 0x70, 0x09, 0x14, 0xaa, 0x02, 0xb1, 0x7a, 0x13,
0x7d, 0x45, 0x8e, 0x83, 0xda, 0x08, 0x66, 0xbb, 0xf2, 0xee, 0xc3, 0xda, 0xce, 0xe6, 0x93, 0xca,
0xea, 0x2a, 0xfa, 0x2a, 0xc7, 0x60, 0x23, 0xb5, 0xc5, 0x18, 0x92, 0xeb, 0x35, 0xf4, 0x35, 0x05,
0x43, 0x6c, 0xf0, 0x12, 0x98, 0xac, 0x49, 0xf9, 0x5d, 0x5d, 0x47, 0x5f, 0x4f, 0x78, 0x5b, 0xa7,
0xa8, 0x6a, 0x8c, 0xb2, 0xd1, 0x37, 0x12, 0x28, 0x3b, 0x4e, 0x20, 0x05, 0xdd, 0x42, 0xdf, 0x4c,
0x80, 0xa4, 0x2c, 0xd3, 0xdd, 0x39, 0xe8, 0x5b, 0x09, 0x90, 0x83, 0xfd, 0x49, 0x31, 0xdd, 0xae,
0xd5, 0xd0, 0xb7, 0x13, 0xa8, 0xdb, 0x18, 0x25, 0xc5, 0xb4, 0x51, 0xab, 0xa1, 0xef, 0x24, 0x50,
0x1b, 0x8b, 0x2f, 0xc0, 0x84, 0xfa, 0xa0, 0x53, 0x00, 0x86, 0xc7, 0xde, 0x88, 0x1a, 0x1e, 0x7c,
0x1b, 0xe4, 0xeb, 0x81, 0x78, 0xa9, 0x81, 0x72, 0xa7, 0xbd, 0x00, 0x91, 0xd1, 0x8b, 0xf7, 0x01,
0x4c, 0x0e, 0x29, 0x61, 0x11, 0x98, 0x2f, 0xfd, 0x13, 0xe6, 0x02, 0xff, 0x0a, 0x67, 0xc1, 0x19,
0x7a, 0xfb, 0xe4, 0x88, 0x8d, 0x7e, 0xb9, 0x9b, 0xdb, 0x30, 0x62, 0x06, 0x79, 0x20, 0x29, 0x33,
0x98, 0x29, 0x0c, 0xa6, 0xcc, 0x50, 0x06, 0xb3, 0x69, 0xa3, 0x47, 0x99, 0x63, 0x22, 0x85, 0x63,
0x22, 0x9d, 0x43, 0x19, 0x31, 0xca, 0x1c, 0xc3, 0x29, 0x1c, 0xc3, 0x49, 0x8e, 0xc4, 0x28, 0x51,
0xe6, 0x98, 0x4e, 0xe1, 0x98, 0x4e, 0xe7, 0x50, 0x46, 0x86, 0x32, 0x07, 0x4c, 0xe1, 0x80, 0x32,
0xc7, 0x43, 0x30, 0x9f, 0x3e, 0x18, 0x94, 0x59, 0x46, 0x53, 0x58, 0x46, 0x33, 0x58, 0xd4, 0xe1,
0x9f, 0xcc, 0x32, 0x92, 0xc2, 0x32, 0x22, 0xb3, 0x54, 0x01, 0xca, 0x1a, 0xef, 0xc9, 0x3c, 0x53,
0x29, 0x3c, 0x53, 0x59, 0x3c, 0xda, 0xf8, 0x4e, 0xe6, 0x29, 0xa6, 0xf0, 0x14, 0x53, 0xbb, 0x4d,
0x1e, 0xd2, 0x9d, 0xd6, 0xaf, 0x39, 0x99, 0x61, 0x13, 0xcc, 0xa4, 0xcc, 0xe3, 0x4e, 0xa3, 0x30,
0x64, 0x8a, 0x7b, 0xa0, 0xa8, 0x0f, 0xdf, 0xe4, 0xf5, 0x63, 0x29, 0xeb, 0xc7, 0x52, 0x9a, 0x44,
0x1f, 0xb4, 0xc9, 0x1c, 0xe3, 0x29, 0x1c, 0xe3, 0xc9, 0x6d, 0xe8, 0x13, 0xb5, 0xd3, 0x28, 0x0a,
0x32, 0x45, 0x08, 0xce, 0xf5, 0x19, 0x99, 0xa5, 0x50, 0xbd, 0x23, 0x53, 0xbd, 0xc6, 0xfb, 0x2a,
0xc9, 0xe7, 0x31, 0x38, 0xdf, 0x6f, 0x66, 0x96, 0xe2, 0x74, 0x55, 0x75, 0xda, 0xf7, 0x15, 0x96,
0xe4, 0xa8, 0x49, 0x1b, 0x2e, 0x6d, 0x56, 0x96, 0xe2, 0xe4, 0xae, 0xec, 0x64, 0xd0, 0x97, 0x5a,
0x92, 0x37, 0x0f, 0x9c, 0xcd, 0x9c, 0x97, 0xa5, 0xb8, 0x5b, 0x51, 0xdd, 0x65, 0xbf, 0xea, 0x8a,
0x5d, 0x2c, 0xdd, 0x01, 0x40, 0x9a, 0xec, 0x8d, 0x02, 0xb3, 0xba, 0xbb, 0x5b, 0x1c, 0xc2, 0xbf,
0x94, 0x37, 0xdd, 0xa2, 0x41, 0x7f, 0x79, 0x51, 0xcc, 0x61, 0x77, 0x3b, 0x95, 0x47, 0xc5, 0xff,
0xf2, 0xff, 0x8c, 0xf2, 0x84, 0x18, 0x45, 0xe1, 0x53, 0x65, 0xe9, 0x0d, 0x30, 0xa9, 0x0d, 0x24,
0x0b, 0xc0, 0xa8, 0xf3, 0x03, 0xa5, 0x7e, 0xed, 0x16, 0x00, 0xf1, 0xbf, 0x61, 0x82, 0x53, 0x20,
0xbf, 0xbf, 0xb3, 0xf7, 0xb4, 0xf2, 0x60, 0xbb, 0xba, 0x5d, 0x79, 0x58, 0x1c, 0x82, 0x05, 0x30,
0xf6, 0xd4, 0xdd, 0x7d, 0xb6, 0x5b, 0xde, 0xaf, 0x16, 0x0d, 0x38, 0x06, 0x86, 0x1f, 0xef, 0xed,
0xee, 0x14, 0x73, 0xd7, 0xee, 0x83, 0xbc, 0x3c, 0x0f, 0x9c, 0x02, 0xf9, 0xea, 0xae, 0x5b, 0xd9,
0x7e, 0xb4, 0x53, 0xa3, 0x91, 0x4a, 0x06, 0x1a, 0xb1, 0x62, 0x78, 0x51, 0xcc, 0x95, 0x2f, 0x82,
0x0b, 0xf5, 0xa0, 0x95, 0xf8, 0xc3, 0x4c, 0x4a, 0xce, 0xc1, 0x08, 0xb1, 0xae, 0xff, 0x2f, 0x00,
0x00, 0xff, 0xff, 0x46, 0x1f, 0xdb, 0xdc, 0xeb, 0x26, 0x00, 0x00,
0x07, 0xe0, 0xa6, 0x02, 0xb8, 0xaf, 0xc5, 0x2d, 0x5b, 0x65, 0x6e, 0xc7, 0xe6, 0xf2, 0xf8, 0xce,
0x80, 0xdc, 0x8e, 0xbd, 0xaf, 0xc5, 0x2d, 0x5b, 0xe1, 0xc7, 0xc1, 0x0c, 0xe6, 0x66, 0xda, 0x26,
0x24, 0xf5, 0x2e, 0x61, 0x5f, 0xed, 0xcb, 0xce, 0x74, 0x96, 0xfd, 0xa0, 0xfc, 0x38, 0x50, 0xd5,
0xae, 0x78, 0x70, 0x6c, 0xa1, 0xc4, 0x1f, 0x19, 0xd4, 0x83, 0x63, 0xb3, 0x1f, 0x9a, 0x07, 0x61,
0x87, 0x47, 0x60, 0x8e, 0xe4, 0x87, 0x6f, 0x42, 0x28, 0xf8, 0x3d, 0xe2, 0x63, 0xbd, 0x7f, 0x8e,
0x18, 0x98, 0xff, 0xa4, 0x5e, 0x70, 0xc8, 0xfa, 0x15, 0xd5, 0x0f, 0xae, 0x04, 0xdf, 0xcb, 0xd6,
0xc0, 0x7e, 0x1c, 0x9b, 0xff, 0xd4, 0xfd, 0xc4, 0x57, 0xd4, 0xfb, 0x95, 0x1e, 0x1a, 0xe5, 0x41,
0xef, 0x57, 0x72, 0x9c, 0x68, 0xf7, 0x2b, 0x3d, 0x62, 0x9e, 0x81, 0x62, 0xcc, 0xca, 0xce, 0x98,
0xfb, 0x84, 0xf6, 0xad, 0xd3, 0x69, 0xe9, 0xe9, 0x43, 0x79, 0x27, 0x5b, 0x8a, 0x11, 0xee, 0x02,
0xec, 0x89, 0x9c, 0x46, 0xf4, 0x48, 0x7a, 0x40, 0x58, 0xaf, 0xf5, 0x65, 0xc5, 0xe7, 0x14, 0xfe,
0x9f, 0x52, 0xe6, 0x5b, 0xb1, 0x45, 0xb4, 0x3b, 0x95, 0x42, 0x76, 0x7e, 0x55, 0x06, 0x69, 0x77,
0x02, 0xa5, 0x9f, 0x52, 0xbb, 0x4b, 0x56, 0x9e, 0x04, 0xc6, 0x4d, 0x8f, 0xbc, 0xea, 0x00, 0x49,
0xa0, 0xcb, 0xc9, 0x69, 0x18, 0x27, 0x41, 0x32, 0xc2, 0x0e, 0x38, 0x2b, 0x11, 0x6b, 0x87, 0xe4,
0x43, 0xe2, 0xe1, 0xe6, 0x00, 0x1e, 0x94, 0x63, 0x91, 0x7a, 0x9a, 0x6f, 0xa5, 0x5e, 0x84, 0x11,
0x58, 0x94, 0x3c, 0xea, 0xa7, 0xe6, 0x36, 0x71, 0xe9, 0x0c, 0xe0, 0x52, 0x3d, 0x33, 0xa9, 0xcf,
0x85, 0x56, 0xfa, 0x55, 0x78, 0x0c, 0xe6, 0x93, 0xdb, 0x24, 0x47, 0xdf, 0xce, 0x20, 0xf7, 0x80,
0xb4, 0x0d, 0x7c, 0xf4, 0x49, 0xf7, 0x80, 0x76, 0x05, 0xbe, 0x0f, 0x16, 0x52, 0x76, 0x47, 0x3c,
0x3d, 0x22, 0x9e, 0x36, 0x06, 0xdf, 0x5a, 0xec, 0x6a, 0xb6, 0x95, 0x72, 0x09, 0x2e, 0x83, 0x42,
0xd0, 0xf6, 0x83, 0x23, 0x7e, 0xdc, 0x04, 0xf8, 0x11, 0x7b, 0x7b, 0xc8, 0xcd, 0x13, 0x2b, 0x3b,
0x3c, 0x3e, 0x06, 0x66, 0x29, 0x48, 0xab, 0x6d, 0xe7, 0xb5, 0x1e, 0xb7, 0xb6, 0x87, 0x5c, 0x48,
0x68, 0xd4, 0x5a, 0x8a, 0x08, 0x58, 0xb7, 0x7f, 0xc0, 0x27, 0x12, 0xc4, 0xca, 0x7a, 0xf7, 0x22,
0xa0, 0x5f, 0x59, 0xdb, 0x86, 0x6c, 0xbc, 0x01, 0x88, 0x91, 0x76, 0xe1, 0x05, 0x00, 0x18, 0x04,
0xdf, 0x87, 0x11, 0x7e, 0x10, 0xdd, 0x1e, 0x72, 0xc7, 0x29, 0x02, 0xdf, 0x5b, 0xca, 0x56, 0x1d,
0x1b, 0x75, 0x2d, 0xa3, 0x34, 0xac, 0x6c, 0xd5, 0xb1, 0x63, 0x47, 0x54, 0x7b, 0x7a, 0xf8, 0xf1,
0x58, 0x38, 0xa2, 0x62, 0x22, 0x78, 0x98, 0x90, 0xbc, 0xc2, 0x8f, 0xc6, 0x82, 0x87, 0x09, 0x43,
0x85, 0x47, 0x43, 0xca, 0xf6, 0xe1, 0xe0, 0x8f, 0x78, 0x22, 0x66, 0x52, 0x9e, 0x3d, 0xe9, 0x69,
0x8c, 0x88, 0x0c, 0x9b, 0xa6, 0xa1, 0x5f, 0x19, 0x24, 0xf7, 0x8b, 0x2b, 0x74, 0xdc, 0xb6, 0xc2,
0xe7, 0x3c, 0x2b, 0x78, 0xab, 0xef, 0x79, 0xcd, 0x9e, 0x1f, 0x3f, 0xa6, 0x61, 0xd3, 0x33, 0xba,
0x0e, 0xba, 0x60, 0x5e, 0x9d, 0xd1, 0x08, 0xc6, 0x5f, 0x1b, 0xec, 0xd1, 0x56, 0x67, 0x24, 0x7a,
0x47, 0x29, 0x67, 0x95, 0x49, 0x4e, 0x06, 0xa7, 0x63, 0x0b, 0xce, 0xdf, 0xf4, 0xe1, 0x74, 0xec,
0x24, 0xa7, 0x63, 0x73, 0xce, 0x03, 0xe9, 0x21, 0xbf, 0xa7, 0x06, 0xfa, 0x5b, 0x4a, 0x7a, 0x3e,
0x41, 0x7a, 0x20, 0x45, 0x3a, 0xa7, 0x0e, 0x89, 0xb2, 0x68, 0xa5, 0x58, 0x7f, 0xd7, 0x8f, 0x96,
0x07, 0x3b, 0xa7, 0x8e, 0x94, 0xd2, 0x32, 0x40, 0x1a, 0x47, 0xb0, 0xfe, 0x3e, 0x2b, 0x03, 0xa4,
0x97, 0xb4, 0x0c, 0x10, 0x5b, 0x5a, 0xa8, 0xb4, 0xd3, 0x04, 0xe9, 0x1f, 0xb2, 0x42, 0xa5, 0xcd,
0xa7, 0x85, 0x4a, 0x8d, 0x69, 0xb4, 0x4c, 0x61, 0x38, 0xed, 0x1f, 0xb3, 0x68, 0xe9, 0x4d, 0xa8,
0xd1, 0x52, 0x63, 0x5a, 0x06, 0xc8, 0x3d, 0x2a, 0x58, 0xff, 0x94, 0x95, 0x01, 0x72, 0xdb, 0x6a,
0x19, 0x20, 0x36, 0xce, 0xb9, 0x27, 0x3d, 0x1c, 0x28, 0xcd, 0xff, 0x67, 0x83, 0xc8, 0x60, 0xdf,
0xe6, 0x97, 0x1f, 0x0a, 0xa5, 0x20, 0xd5, 0x91, 0x81, 0x60, 0xfc, 0x8b, 0xc1, 0x9e, 0xb4, 0xfa,
0x35, 0xbf, 0x32, 0x58, 0xc8, 0xe0, 0x94, 0x1a, 0xea, 0xaf, 0x7d, 0x38, 0x45, 0xf3, 0x2b, 0x53,
0x08, 0xa9, 0x46, 0xda, 0x30, 0x42, 0x90, 0xfe, 0x8d, 0x92, 0x9e, 0xd2, 0xfc, 0xea, 0xcc, 0x22,
0x8b, 0x56, 0x8a, 0xf5, 0xef, 0xfd, 0x68, 0x45, 0xf3, 0xab, 0x13, 0x8e, 0xb4, 0x0c, 0xa8, 0xcd,
0xff, 0x8f, 0xac, 0x0c, 0xc8, 0xcd, 0xaf, 0x0c, 0x03, 0xd2, 0x42, 0xd5, 0x9a, 0xff, 0x9f, 0x59,
0xa1, 0x2a, 0xcd, 0xaf, 0x8e, 0x0e, 0xd2, 0x68, 0xb5, 0xe6, 0xff, 0x57, 0x16, 0xad, 0xd2, 0xfc,
0xea, 0xb3, 0x68, 0x5a, 0x06, 0xd4, 0xe6, 0xff, 0x77, 0x56, 0x06, 0xe4, 0xe6, 0x57, 0x06, 0x0e,
0x9c, 0xf3, 0xa1, 0x34, 0xd7, 0xe5, 0xef, 0x70, 0xd0, 0x77, 0x73, 0x6c, 0x4e, 0x96, 0xd8, 0x3b,
0x43, 0xc4, 0x33, 0x5f, 0x6e, 0x81, 0x8f, 0x80, 0x18, 0x1a, 0xd6, 0xc4, 0xcb, 0x1a, 0xf4, 0xbd,
0x5c, 0xc6, 0xf9, 0xf1, 0x94, 0x43, 0x5c, 0xe1, 0x5f, 0x98, 0xe0, 0x47, 0xc1, 0x8c, 0x34, 0xc4,
0xe6, 0x2f, 0x8e, 0xd0, 0xf7, 0xb3, 0xc8, 0xaa, 0x18, 0xf3, 0xd8, 0x8b, 0x5e, 0xc6, 0x64, 0xc2,
0x04, 0xb7, 0xd4, 0xb9, 0x70, 0xaf, 0xde, 0x45, 0x3f, 0xa0, 0x44, 0x0b, 0x69, 0x45, 0xe8, 0xd5,
0xbb, 0xca, 0xc4, 0xb8, 0x57, 0xef, 0xc2, 0x4d, 0x20, 0x66, 0x8b, 0x35, 0xaf, 0x7d, 0x82, 0x7e,
0x48, 0xd7, 0xcf, 0x26, 0xd6, 0x6f, 0xb5, 0x4f, 0xdc, 0x3c, 0x87, 0x6e, 0xb5, 0x4f, 0xe0, 0x5d,
0x69, 0xd6, 0xfc, 0x0a, 0x97, 0x01, 0xfd, 0x88, 0xae, 0x9d, 0x4f, 0xac, 0xa5, 0x55, 0x12, 0xd3,
0x4d, 0xf2, 0x15, 0x97, 0x27, 0x6e, 0x50, 0x5e, 0x9e, 0x1f, 0xe7, 0x48, 0xb5, 0xfb, 0x95, 0x47,
0xf4, 0xa5, 0x54, 0x1e, 0x41, 0x14, 0x97, 0xe7, 0x27, 0xb9, 0x0c, 0x85, 0x93, 0xca, 0xc3, 0x97,
0xc5, 0xe5, 0x91, 0xb9, 0x48, 0x79, 0x48, 0x75, 0x7e, 0x9a, 0xc5, 0x25, 0x55, 0x27, 0x1e, 0x0a,
0xb2, 0x55, 0xb8, 0x3a, 0xf2, 0xad, 0x82, 0xab, 0xf3, 0x4b, 0x4a, 0x94, 0x5d, 0x1d, 0xe9, 0xee,
0x60, 0xd5, 0x11, 0x14, 0xb8, 0x3a, 0x3f, 0xa3, 0xeb, 0x33, 0xaa, 0xc3, 0xa1, 0xac, 0x3a, 0x62,
0x25, 0xad, 0xce, 0xcf, 0xe9, 0xda, 0xcc, 0xea, 0x70, 0x38, 0xad, 0xce, 0x05, 0x00, 0xc8, 0xfe,
0xdb, 0x5e, 0xcb, 0x5f, 0x43, 0x9f, 0x36, 0xc9, 0x6b, 0x28, 0xc9, 0x04, 0x2d, 0x90, 0xa7, 0xfd,
0x8b, 0xbf, 0xae, 0xa3, 0xcf, 0xc8, 0x88, 0x5d, 0x6c, 0x82, 0x17, 0x41, 0xa1, 0x16, 0x43, 0x36,
0xd0, 0x67, 0x19, 0xa4, 0xca, 0x21, 0x1b, 0x70, 0x09, 0x4c, 0x50, 0x04, 0x81, 0xd8, 0x35, 0xf4,
0x39, 0x9d, 0x86, 0xfc, 0x3d, 0x49, 0xbe, 0xad, 0x62, 0xc8, 0x4d, 0xf4, 0x79, 0x8a, 0x90, 0x6d,
0x70, 0x99, 0xd3, 0xac, 0x12, 0x1e, 0x07, 0x7d, 0x41, 0x01, 0x61, 0x1e, 0x47, 0xec, 0x08, 0x7f,
0xbb, 0x85, 0xbe, 0xa8, 0x3b, 0xba, 0x85, 0x01, 0x22, 0xb4, 0x4d, 0xf4, 0x25, 0x3d, 0xda, 0xcd,
0x78, 0xcb, 0xf8, 0xeb, 0x6d, 0xf4, 0x65, 0x9d, 0xe2, 0x36, 0x5c, 0x02, 0x85, 0xaa, 0x40, 0xac,
0xad, 0xa2, 0xaf, 0xb0, 0x38, 0x04, 0xc9, 0xda, 0x2a, 0xc1, 0xec, 0x54, 0xde, 0x7d, 0x50, 0xdb,
0xdd, 0x7a, 0x5c, 0x59, 0x5b, 0x43, 0x5f, 0xe5, 0x18, 0x6c, 0xa4, 0xb6, 0x18, 0x43, 0x72, 0xbd,
0x8e, 0xbe, 0xa6, 0x60, 0x88, 0x0d, 0x5e, 0x02, 0x93, 0x35, 0x29, 0xbf, 0x6b, 0x1b, 0xe8, 0xeb,
0x09, 0x6f, 0x1b, 0x14, 0x55, 0x8d, 0x51, 0x36, 0xfa, 0x46, 0x02, 0x65, 0xc7, 0x09, 0xa4, 0xa0,
0x9b, 0xe8, 0x9b, 0x72, 0x02, 0x09, 0x48, 0xca, 0x32, 0xdd, 0x9d, 0x83, 0xbe, 0x95, 0x00, 0x39,
0xd8, 0x9f, 0x14, 0xd3, 0xad, 0x5a, 0x0d, 0x7d, 0x3b, 0x81, 0xba, 0x85, 0x51, 0x52, 0x4c, 0x9b,
0xb5, 0x1a, 0xfa, 0x4e, 0x22, 0xaa, 0xcd, 0xc5, 0xe7, 0x60, 0x42, 0x7d, 0xd0, 0x29, 0x00, 0xc3,
0x63, 0x6f, 0x44, 0x0d, 0x0f, 0xbe, 0x0d, 0xf2, 0xf5, 0x40, 0xbc, 0xd4, 0x40, 0xb9, 0xd3, 0x5e,
0x80, 0xc8, 0xe8, 0xc5, 0x7b, 0x00, 0x26, 0x87, 0x94, 0xb0, 0x08, 0xcc, 0x97, 0xfe, 0x09, 0x73,
0x81, 0x7f, 0x85, 0xb3, 0xe0, 0x0c, 0xbd, 0x7d, 0x72, 0xc4, 0x46, 0xbf, 0xdc, 0xc9, 0x6d, 0x1a,
0x31, 0x83, 0x3c, 0x90, 0x94, 0x19, 0xcc, 0x14, 0x06, 0x53, 0x66, 0x28, 0x83, 0xd9, 0xb4, 0xd1,
0xa3, 0xcc, 0x31, 0x91, 0xc2, 0x31, 0x91, 0xce, 0xa1, 0x8c, 0x18, 0x65, 0x8e, 0xe1, 0x14, 0x8e,
0xe1, 0x24, 0x47, 0x62, 0x94, 0x28, 0x73, 0x4c, 0xa7, 0x70, 0x4c, 0xa7, 0x73, 0x28, 0x23, 0x43,
0x99, 0x03, 0xa6, 0x70, 0x40, 0x99, 0xe3, 0x01, 0x98, 0x4f, 0x1f, 0x0c, 0xca, 0x2c, 0xa3, 0x29,
0x2c, 0xa3, 0x19, 0x2c, 0xea, 0xf0, 0x4f, 0x66, 0x19, 0x49, 0x61, 0x19, 0x91, 0x59, 0xaa, 0x00,
0x65, 0x8d, 0xf7, 0x64, 0x9e, 0xa9, 0x14, 0x9e, 0xa9, 0x2c, 0x1e, 0x6d, 0x7c, 0x27, 0xf3, 0x14,
0x53, 0x78, 0x8a, 0xa9, 0xdd, 0x26, 0x0f, 0xe9, 0x4e, 0xeb, 0xd7, 0x9c, 0xcc, 0xb0, 0x05, 0x66,
0x52, 0xe6, 0x71, 0xa7, 0x51, 0x18, 0x32, 0xc5, 0x5d, 0x50, 0xd4, 0x87, 0x6f, 0xf2, 0xfa, 0xb1,
0x94, 0xf5, 0x63, 0x29, 0x4d, 0xa2, 0x0f, 0xda, 0x64, 0x8e, 0xf1, 0x14, 0x8e, 0xf1, 0xe4, 0x36,
0xf4, 0x89, 0xda, 0x69, 0x14, 0x05, 0x99, 0x22, 0x04, 0xe7, 0xfa, 0x8c, 0xcc, 0x52, 0xa8, 0xde,
0x91, 0xa9, 0x5e, 0xe3, 0x7d, 0x95, 0xe4, 0xf3, 0x18, 0x9c, 0xef, 0x37, 0x33, 0x4b, 0x71, 0xba,
0xa6, 0x3a, 0xed, 0xfb, 0x0a, 0x4b, 0x72, 0xd4, 0xa4, 0x0d, 0x97, 0x36, 0x2b, 0x4b, 0x71, 0x72,
0x47, 0x76, 0x32, 0xe8, 0x4b, 0x2d, 0xc9, 0x9b, 0x07, 0xce, 0x66, 0xce, 0xcb, 0x52, 0xdc, 0xad,
0xa8, 0xee, 0xb2, 0x5f, 0x75, 0xc5, 0x2e, 0x96, 0x6e, 0x03, 0x20, 0x4d, 0xf6, 0x46, 0x81, 0x59,
0xdd, 0xdb, 0x2b, 0x0e, 0xe1, 0x5f, 0xca, 0x5b, 0x6e, 0xd1, 0xa0, 0xbf, 0x3c, 0x2f, 0xe6, 0xb0,
0xbb, 0xdd, 0xca, 0xc3, 0xe2, 0x7f, 0xf9, 0x7f, 0x46, 0x79, 0x42, 0x8c, 0xa2, 0xf0, 0xa9, 0xb2,
0xf4, 0x06, 0x98, 0xd4, 0x06, 0x92, 0x05, 0x60, 0xd4, 0xf9, 0x81, 0x52, 0xbf, 0x76, 0x13, 0x80,
0xf8, 0xdf, 0x30, 0xc1, 0x29, 0x90, 0x3f, 0xd8, 0xdd, 0x7f, 0x52, 0xb9, 0xbf, 0x53, 0xdd, 0xa9,
0x3c, 0x28, 0x0e, 0xc1, 0x02, 0x18, 0x7b, 0xe2, 0xee, 0x3d, 0xdd, 0x2b, 0x1f, 0x54, 0x8b, 0x06,
0x1c, 0x03, 0xc3, 0x8f, 0xf6, 0xf7, 0x76, 0x8b, 0xb9, 0x6b, 0xf7, 0x40, 0x5e, 0x9e, 0x07, 0x4e,
0x81, 0x7c, 0x75, 0xcf, 0xad, 0xec, 0x3c, 0xdc, 0xad, 0xd1, 0x48, 0x25, 0x03, 0x8d, 0x58, 0x31,
0x3c, 0x2f, 0xe6, 0xca, 0x17, 0xc1, 0x85, 0x7a, 0xd0, 0x4a, 0xfc, 0x61, 0x26, 0x25, 0xe7, 0xc5,
0x08, 0xb1, 0x6e, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x33, 0xc2, 0x0c, 0xb6, 0xeb, 0x26, 0x00,
0x00,
}

View File

@@ -0,0 +1,93 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
// Package descriptor provides functions for obtaining protocol buffer
// descriptors for generated Go types.
//
// These functions cannot go in package proto because they depend on the
// generated protobuf descriptor messages, which themselves depend on proto.
package descriptor
import (
"bytes"
"compress/gzip"
"fmt"
"io/ioutil"
"github.com/golang/protobuf/proto"
protobuf "google.golang.org/genproto/protobuf"
)
// extractFile extracts a FileDescriptorProto from a gzip'd buffer.
func extractFile(gz []byte) (*protobuf.FileDescriptorProto, error) {
r, err := gzip.NewReader(bytes.NewReader(gz))
if err != nil {
return nil, fmt.Errorf("failed to open gzip reader: %v", err)
}
defer r.Close()
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("failed to uncompress descriptor: %v", err)
}
fd := new(protobuf.FileDescriptorProto)
if err := proto.Unmarshal(b, fd); err != nil {
return nil, fmt.Errorf("malformed FileDescriptorProto: %v", err)
}
return fd, nil
}
// Message is a proto.Message with a method to return its descriptor.
//
// Message types generated by the protocol compiler always satisfy
// the Message interface.
type Message interface {
proto.Message
Descriptor() ([]byte, []int)
}
// ForMessage returns a FileDescriptorProto and a DescriptorProto from within it
// describing the given message.
func ForMessage(msg Message) (fd *protobuf.FileDescriptorProto, md *protobuf.DescriptorProto) {
gz, path := msg.Descriptor()
fd, err := extractFile(gz)
if err != nil {
panic(fmt.Sprintf("invalid FileDescriptorProto for %T: %v", msg, err))
}
md = fd.MessageType[path[0]]
for _, i := range path[1:] {
md = md.NestedType[i]
}
return fd, md
}

View File

@@ -0,0 +1,32 @@
package descriptor_test
import (
"fmt"
"testing"
"github.com/golang/protobuf/descriptor"
tpb "github.com/golang/protobuf/proto/testdata"
protobuf "google.golang.org/genproto/protobuf"
)
func TestMessage(t *testing.T) {
var msg *protobuf.DescriptorProto
fd, md := descriptor.ForMessage(msg)
if pkg, want := fd.GetPackage(), "google.protobuf"; pkg != want {
t.Errorf("descriptor.ForMessage(%T).GetPackage() = %q; want %q", msg, pkg, want)
}
if name, want := md.GetName(), "DescriptorProto"; name != want {
t.Fatalf("descriptor.ForMessage(%T).GetName() = %q; want %q", msg, name, want)
}
}
func Example_Options() {
var msg *tpb.MyMessageSet
_, md := descriptor.ForMessage(msg)
if md.GetOptions().GetMessageSetWireFormat() {
fmt.Printf("%v uses option message_set_wire_format.\n", md.GetName())
}
// Output:
// MyMessageSet uses option message_set_wire_format.
}

View File

@@ -585,7 +585,14 @@ func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMe
case "Any":
return fmt.Errorf("unmarshaling Any not supported yet")
case "Duration":
unq, err := strconv.Unquote(string(inputValue))
ivStr := string(inputValue)
if ivStr == "null" {
target.Field(0).SetInt(0)
target.Field(1).SetInt(0)
return nil
}
unq, err := strconv.Unquote(ivStr)
if err != nil {
return err
}
@@ -600,7 +607,14 @@ func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMe
target.Field(1).SetInt(ns)
return nil
case "Timestamp":
unq, err := strconv.Unquote(string(inputValue))
ivStr := string(inputValue)
if ivStr == "null" {
target.Field(0).SetInt(0)
target.Field(1).SetInt(0)
return nil
}
unq, err := strconv.Unquote(ivStr)
if err != nil {
return err
}

View File

@@ -467,9 +467,11 @@ var unmarshalingTests = []struct {
{"camelName input", Unmarshaler{}, `{"oBool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
{"Duration", Unmarshaler{}, `{"dur":"3.000s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}},
{"null Duration", Unmarshaler{}, `{"dur":null}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 0}}},
{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20.021Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}},
{"PreEpochTimestamp", Unmarshaler{}, `{"ts":"1969-12-31T23:59:58.999999995Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -2, Nanos: 999999995}}},
{"ZeroTimeTimestamp", Unmarshaler{}, `{"ts":"0001-01-01T00:00:00Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -62135596800, Nanos: 0}}},
{"null Timestamp", Unmarshaler{}, `{"ts":null}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 0, Nanos: 0}}},
{"DoubleValue", Unmarshaler{}, `{"dbl":1.2}`, &pb.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}},
{"FloatValue", Unmarshaler{}, `{"flt":1.2}`, &pb.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}},

View File

@@ -71,6 +71,13 @@ func (m *Simple3) String() string { return proto.CompactTextString(m)
func (*Simple3) ProtoMessage() {}
func (*Simple3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Simple3) GetDub() float64 {
if m != nil {
return m.Dub
}
return 0
}
type Mappy struct {
Nummy map[int64]int32 `protobuf:"bytes,1,rep,name=nummy" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
Strry map[string]string `protobuf:"bytes,2,rep,name=strry" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`

View File

@@ -360,7 +360,7 @@ type MsgWithOneof_Salary struct {
Salary int64 `protobuf:"varint,2,opt,name=salary,oneof"`
}
type MsgWithOneof_Country struct {
Country string `protobuf:"bytes,3,opt,name=Country,json=country,oneof"`
Country string `protobuf:"bytes,3,opt,name=Country,oneof"`
}
type MsgWithOneof_HomeAddress struct {
HomeAddress string `protobuf:"bytes,4,opt,name=home_address,json=homeAddress,oneof"`
@@ -559,6 +559,7 @@ var E_Complex_RealExtension = &proto.ExtensionDesc{
Field: 123,
Name: "jsonpb.Complex.real_extension",
Tag: "bytes,123,opt,name=real_extension,json=realExtension",
Filename: "test_objects.proto",
}
type KnownTypes struct {
@@ -680,6 +681,7 @@ var E_Name = &proto.ExtensionDesc{
Field: 124,
Name: "jsonpb.name",
Tag: "bytes,124,opt,name=name",
Filename: "test_objects.proto",
}
func init() {
@@ -699,71 +701,71 @@ func init() {
func init() { proto.RegisterFile("test_objects.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 1055 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x95, 0x51, 0x73, 0xdb, 0x44,
0x10, 0xc7, 0x23, 0xc9, 0x96, 0xec, 0x73, 0x12, 0xcc, 0x4d, 0x4a, 0x15, 0x13, 0x40, 0x63, 0x4a,
0x11, 0x85, 0xba, 0x83, 0xe2, 0xf1, 0x30, 0x85, 0x97, 0xa4, 0x31, 0x94, 0x81, 0x94, 0x99, 0x4b,
0x43, 0x1f, 0x3d, 0x72, 0x7c, 0x71, 0x55, 0x64, 0x9d, 0xe7, 0xee, 0x44, 0xea, 0x81, 0x87, 0x3c,
0xf3, 0xcc, 0x57, 0x80, 0x8f, 0xc0, 0x27, 0xe2, 0x83, 0x74, 0x76, 0x4f, 0xb2, 0x12, 0x3b, 0x7e,
0x8a, 0xf7, 0xf6, 0xbf, 0xff, 0x9c, 0x7e, 0xb7, 0x77, 0x4b, 0xa8, 0xe6, 0x4a, 0x8f, 0xc4, 0xf8,
0x0d, 0xbf, 0xd0, 0xaa, 0x37, 0x97, 0x42, 0x0b, 0xea, 0xbe, 0x51, 0x22, 0x9b, 0x8f, 0x3b, 0xfb,
0x53, 0x21, 0xa6, 0x29, 0x7f, 0x82, 0xab, 0xe3, 0xfc, 0xf2, 0x49, 0x9c, 0x2d, 0x8c, 0xa4, 0xf3,
0xf1, 0x6a, 0x6a, 0x92, 0xcb, 0x58, 0x27, 0x22, 0x2b, 0xf2, 0x07, 0xab, 0x79, 0xa5, 0x65, 0x7e,
0xa1, 0x8b, 0xec, 0x27, 0xab, 0x59, 0x9d, 0xcc, 0xb8, 0xd2, 0xf1, 0x6c, 0xbe, 0xc9, 0xfe, 0x4a,
0xc6, 0xf3, 0x39, 0x97, 0xc5, 0x0e, 0xbb, 0xff, 0xd8, 0xc4, 0x3d, 0x4b, 0x66, 0xf3, 0x94, 0xd3,
0x7b, 0xc4, 0x15, 0xa3, 0xb1, 0x10, 0xa9, 0x6f, 0x05, 0x56, 0xd8, 0x60, 0x75, 0x71, 0x2c, 0x44,
0x4a, 0xef, 0x13, 0x4f, 0x8c, 0x92, 0x4c, 0x1f, 0x46, 0xbe, 0x1d, 0x58, 0x61, 0x9d, 0xb9, 0xe2,
0x47, 0x88, 0x96, 0x89, 0x41, 0xdf, 0x77, 0x02, 0x2b, 0x74, 0x4c, 0x62, 0xd0, 0xa7, 0xfb, 0xa4,
0x21, 0x46, 0xb9, 0x29, 0xa9, 0x05, 0x56, 0xb8, 0xc3, 0x3c, 0x71, 0x8e, 0x61, 0x95, 0x1a, 0xf4,
0xfd, 0x7a, 0x60, 0x85, 0xb5, 0x22, 0x55, 0x56, 0x29, 0x53, 0xe5, 0x06, 0x56, 0xf8, 0x3e, 0xf3,
0xc4, 0xd9, 0x8d, 0x2a, 0x65, 0xaa, 0xbc, 0xc0, 0x0a, 0x69, 0x91, 0x1a, 0xf4, 0xcd, 0x26, 0x2e,
0x53, 0x11, 0x6b, 0xbf, 0x11, 0x58, 0xa1, 0xcd, 0x5c, 0xf1, 0x3d, 0x44, 0xa6, 0x66, 0x22, 0xf2,
0x71, 0xca, 0xfd, 0x66, 0x60, 0x85, 0x16, 0xf3, 0xc4, 0x09, 0x86, 0x85, 0x9d, 0x96, 0x49, 0x36,
0xf5, 0x49, 0x60, 0x85, 0x4d, 0xb0, 0xc3, 0xd0, 0xd8, 0x8d, 0x17, 0x9a, 0x2b, 0xbf, 0x15, 0x58,
0xe1, 0x36, 0x73, 0xc5, 0x31, 0x44, 0xdd, 0x7f, 0x6d, 0xe2, 0x31, 0x3e, 0xe7, 0xb1, 0x56, 0x00,
0x4a, 0x96, 0xa0, 0x1c, 0x00, 0x25, 0x4b, 0x50, 0x72, 0x09, 0xca, 0x01, 0x50, 0x72, 0x09, 0x4a,
0x2e, 0x41, 0x39, 0x00, 0x4a, 0x2e, 0x41, 0xc9, 0x0a, 0x94, 0x03, 0xa0, 0x64, 0x05, 0x4a, 0x56,
0xa0, 0x1c, 0x00, 0x25, 0x2b, 0x50, 0xb2, 0x02, 0xe5, 0x00, 0x28, 0x79, 0x76, 0xa3, 0x6a, 0x09,
0xca, 0x01, 0x50, 0xb2, 0x02, 0x25, 0x97, 0xa0, 0x1c, 0x00, 0x25, 0x97, 0xa0, 0x64, 0x05, 0xca,
0x01, 0x50, 0xb2, 0x02, 0x25, 0x2b, 0x50, 0x0e, 0x80, 0x92, 0x15, 0x28, 0xb9, 0x04, 0xe5, 0x00,
0x28, 0x69, 0x40, 0xfd, 0x67, 0x13, 0xf7, 0x55, 0x32, 0x99, 0x72, 0x4d, 0x1f, 0x91, 0xfa, 0x85,
0x48, 0x85, 0xc4, 0x7e, 0xda, 0x8d, 0xf6, 0x7a, 0xe6, 0x36, 0xf4, 0x4c, 0xba, 0xf7, 0x0c, 0x72,
0xcc, 0x48, 0xe8, 0x63, 0xf0, 0x33, 0x6a, 0x80, 0xb7, 0x49, 0xed, 0x4a, 0xfc, 0x4b, 0x1f, 0x12,
0x57, 0x61, 0xd7, 0xe2, 0x01, 0xb6, 0xa2, 0xdd, 0x52, 0x6d, 0x7a, 0x99, 0x15, 0x59, 0xfa, 0x85,
0x01, 0x82, 0x4a, 0xd8, 0xe7, 0xba, 0x12, 0x00, 0x15, 0x52, 0x4f, 0x9a, 0x03, 0xf6, 0xf7, 0xd0,
0xf3, 0xbd, 0x52, 0x59, 0x9c, 0x3b, 0x2b, 0xf3, 0xf4, 0x2b, 0xd2, 0x94, 0xa3, 0x52, 0x7c, 0x0f,
0x6d, 0xd7, 0xc4, 0x0d, 0x59, 0xfc, 0xea, 0x7e, 0x46, 0xea, 0x66, 0xd3, 0x1e, 0x71, 0xd8, 0xf0,
0xa4, 0xbd, 0x45, 0x9b, 0xa4, 0xfe, 0x03, 0x1b, 0x0e, 0x5f, 0xb4, 0x2d, 0xda, 0x20, 0xb5, 0xe3,
0x9f, 0xcf, 0x87, 0x6d, 0xbb, 0xfb, 0xb7, 0x4d, 0x6a, 0xa7, 0xf1, 0x5c, 0xd1, 0x6f, 0x49, 0x6b,
0x66, 0xda, 0x05, 0xd8, 0x63, 0x8f, 0xb5, 0xa2, 0x0f, 0x4b, 0x7f, 0x90, 0xf4, 0x4e, 0xb1, 0x7f,
0xce, 0xb4, 0x1c, 0x66, 0x5a, 0x2e, 0x58, 0x73, 0x56, 0xc6, 0xf4, 0x88, 0xec, 0xcc, 0xb0, 0x37,
0xcb, 0xaf, 0xb6, 0xb1, 0xfc, 0xa3, 0xdb, 0xe5, 0xd0, 0xaf, 0xe6, 0xb3, 0x8d, 0x41, 0x6b, 0x56,
0xad, 0x74, 0xbe, 0x23, 0xbb, 0xb7, 0xfd, 0x69, 0x9b, 0x38, 0xbf, 0xf1, 0x05, 0x1e, 0xa3, 0xc3,
0xe0, 0x27, 0xdd, 0x23, 0xf5, 0xdf, 0xe3, 0x34, 0xe7, 0xf8, 0x24, 0x34, 0x99, 0x09, 0x9e, 0xda,
0xdf, 0x58, 0x9d, 0x17, 0xa4, 0xbd, 0x6a, 0x7f, 0xb3, 0xbe, 0x61, 0xea, 0x1f, 0xdc, 0xac, 0x5f,
0x3f, 0x94, 0xca, 0xaf, 0xfb, 0x97, 0x45, 0xb6, 0x4f, 0xd5, 0xf4, 0x55, 0xa2, 0x5f, 0xff, 0x92,
0x71, 0x71, 0x49, 0x3f, 0x20, 0x75, 0x9d, 0xe8, 0x94, 0xa3, 0x5d, 0xf3, 0xf9, 0x16, 0x33, 0x21,
0xf5, 0x89, 0xab, 0xe2, 0x34, 0x96, 0x0b, 0xf4, 0x74, 0x9e, 0x6f, 0xb1, 0x22, 0xa6, 0x1d, 0xe2,
0x3d, 0x13, 0x39, 0xec, 0x04, 0x1f, 0x2a, 0xa8, 0xf1, 0x2e, 0xcc, 0x02, 0xfd, 0x94, 0x6c, 0xbf,
0x16, 0x33, 0x3e, 0x8a, 0x27, 0x13, 0xc9, 0x95, 0xc2, 0xf7, 0x0a, 0x04, 0x2d, 0x58, 0x3d, 0x32,
0x8b, 0xc7, 0x1e, 0xa9, 0xe7, 0x59, 0x22, 0xb2, 0xee, 0x43, 0x52, 0x63, 0x3c, 0x4e, 0xab, 0xcf,
0xb7, 0xf0, 0x65, 0x31, 0xc1, 0xa3, 0x46, 0x63, 0xd2, 0xbe, 0xbe, 0xbe, 0xbe, 0xb6, 0xbb, 0x57,
0xf0, 0x1f, 0xe1, 0x4b, 0xde, 0xd2, 0x03, 0xd2, 0x4c, 0x66, 0xf1, 0x34, 0xc9, 0x60, 0x67, 0x46,
0x5e, 0x2d, 0x54, 0x25, 0xd1, 0x09, 0xd9, 0x95, 0x3c, 0x4e, 0x47, 0xfc, 0xad, 0xe6, 0x99, 0x4a,
0x44, 0x46, 0xb7, 0xab, 0x96, 0x8a, 0x53, 0xff, 0x8f, 0xdb, 0x3d, 0x59, 0xd8, 0xb3, 0x1d, 0x28,
0x1a, 0x96, 0x35, 0xdd, 0xff, 0x6b, 0x84, 0xfc, 0x94, 0x89, 0xab, 0xec, 0xe5, 0x62, 0xce, 0x15,
0x7d, 0x40, 0xec, 0x38, 0xf3, 0x77, 0xb1, 0x74, 0xaf, 0x67, 0x46, 0x41, 0xaf, 0x1c, 0x05, 0xbd,
0xa3, 0x6c, 0xc1, 0xec, 0x38, 0xa3, 0x5f, 0x12, 0x67, 0x92, 0x9b, 0x5b, 0xda, 0x8a, 0xf6, 0xd7,
0x64, 0x27, 0xc5, 0x40, 0x62, 0xa0, 0xa2, 0x9f, 0x13, 0x5b, 0x69, 0x7f, 0x1b, 0xb5, 0xf7, 0xd7,
0xb4, 0x67, 0x38, 0x9c, 0x98, 0xad, 0xe0, 0xf6, 0xdb, 0x5a, 0x15, 0xe7, 0xdb, 0x59, 0x13, 0xbe,
0x2c, 0xe7, 0x14, 0xb3, 0xb5, 0xa2, 0x3d, 0xe2, 0x4c, 0xc6, 0x29, 0x9e, 0x4e, 0x2b, 0x3a, 0x58,
0xdf, 0x01, 0x3e, 0x47, 0xbf, 0x02, 0x64, 0x06, 0x42, 0xfa, 0x98, 0x38, 0x97, 0xa9, 0xc6, 0xc3,
0x82, 0xab, 0xb1, 0xaa, 0xc7, 0x87, 0xad, 0x90, 0x5f, 0xa6, 0x1a, 0xe4, 0x49, 0x31, 0x70, 0xee,
0x92, 0x63, 0xb3, 0x17, 0xf2, 0x64, 0xd0, 0x87, 0xdd, 0xe4, 0x83, 0x3e, 0x0e, 0xa1, 0xbb, 0x76,
0x73, 0x7e, 0x53, 0x9f, 0x0f, 0xfa, 0x68, 0x7f, 0x18, 0xe1, 0x64, 0xda, 0x60, 0x7f, 0x18, 0x95,
0xf6, 0x87, 0x11, 0xda, 0x1f, 0x46, 0x38, 0xae, 0x36, 0xd9, 0x2f, 0xf5, 0x39, 0xea, 0x6b, 0x38,
0x6c, 0x9a, 0x1b, 0x50, 0xc2, 0x6d, 0x33, 0x72, 0xd4, 0x81, 0x3f, 0xbc, 0x1b, 0x64, 0x83, 0xbf,
0x79, 0xc0, 0x0b, 0x7f, 0xa5, 0x25, 0xfd, 0x9a, 0xd4, 0xab, 0x89, 0x77, 0xd7, 0x07, 0xe0, 0xc3,
0x6e, 0x0a, 0x8c, 0xf2, 0x69, 0x40, 0x6a, 0x59, 0x3c, 0xe3, 0x2b, 0x2d, 0xfa, 0x27, 0xbe, 0x05,
0x98, 0x79, 0x17, 0x00, 0x00, 0xff, 0xff, 0xda, 0x8b, 0x4a, 0x7a, 0x0e, 0x09, 0x00, 0x00,
// 1054 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x95, 0xdf, 0x72, 0xdb, 0x44,
0x14, 0xc6, 0x23, 0xc9, 0x96, 0xed, 0x75, 0x12, 0xcc, 0x4e, 0x4a, 0x15, 0x13, 0x40, 0x63, 0x4a,
0x11, 0x85, 0xba, 0x83, 0xe2, 0xf1, 0x30, 0x85, 0x9b, 0xa4, 0x31, 0x94, 0x81, 0x94, 0x99, 0x4d,
0x43, 0x2f, 0x3d, 0x72, 0xbc, 0x71, 0x55, 0x64, 0xad, 0x67, 0x77, 0x45, 0xea, 0x81, 0x8b, 0x5c,
0x73, 0xcd, 0x2b, 0xc0, 0x23, 0xf0, 0x44, 0x3c, 0x48, 0xe7, 0x9c, 0xd5, 0x9f, 0xc4, 0x8e, 0xaf,
0xe2, 0xb3, 0xe7, 0x3b, 0x5f, 0x56, 0xbf, 0x3d, 0xbb, 0x87, 0x50, 0xcd, 0x95, 0x1e, 0x8b, 0xc9,
0x1b, 0x7e, 0xa1, 0x55, 0x7f, 0x21, 0x85, 0x16, 0xd4, 0x7d, 0xa3, 0x44, 0xba, 0x98, 0x74, 0xf7,
0x67, 0x42, 0xcc, 0x12, 0xfe, 0x04, 0x57, 0x27, 0xd9, 0xe5, 0x93, 0x28, 0x5d, 0x1a, 0x49, 0xf7,
0xe3, 0xd5, 0xd4, 0x34, 0x93, 0x91, 0x8e, 0x45, 0x9a, 0xe7, 0x0f, 0x56, 0xf3, 0x4a, 0xcb, 0xec,
0x42, 0xe7, 0xd9, 0x4f, 0x56, 0xb3, 0x3a, 0x9e, 0x73, 0xa5, 0xa3, 0xf9, 0x62, 0x93, 0xfd, 0x95,
0x8c, 0x16, 0x0b, 0x2e, 0xf3, 0x1d, 0xf6, 0xfe, 0xb1, 0x89, 0x7b, 0x16, 0xcf, 0x17, 0x09, 0xa7,
0xf7, 0x88, 0x2b, 0xc6, 0x13, 0x21, 0x12, 0xcf, 0xf2, 0xad, 0xa0, 0xc9, 0xea, 0xe2, 0x58, 0x88,
0x84, 0xde, 0x27, 0x0d, 0x31, 0x8e, 0x53, 0x7d, 0x18, 0x7a, 0xb6, 0x6f, 0x05, 0x75, 0xe6, 0x8a,
0x1f, 0x21, 0x2a, 0x13, 0xc3, 0x81, 0xe7, 0xf8, 0x56, 0xe0, 0x98, 0xc4, 0x70, 0x40, 0xf7, 0x49,
0x53, 0x8c, 0x33, 0x53, 0x52, 0xf3, 0xad, 0x60, 0x87, 0x35, 0xc4, 0x39, 0x86, 0x55, 0x6a, 0x38,
0xf0, 0xea, 0xbe, 0x15, 0xd4, 0xf2, 0x54, 0x51, 0xa5, 0x4c, 0x95, 0xeb, 0x5b, 0xc1, 0xfb, 0xac,
0x21, 0xce, 0x6e, 0x54, 0x29, 0x53, 0xd5, 0xf0, 0xad, 0x80, 0xe6, 0xa9, 0xe1, 0xc0, 0x6c, 0xe2,
0x32, 0x11, 0x91, 0xf6, 0x9a, 0xbe, 0x15, 0xd8, 0xcc, 0x15, 0xdf, 0x43, 0x64, 0x6a, 0xa6, 0x22,
0x9b, 0x24, 0xdc, 0x6b, 0xf9, 0x56, 0x60, 0xb1, 0x86, 0x38, 0xc1, 0x30, 0xb7, 0xd3, 0x32, 0x4e,
0x67, 0x1e, 0xf1, 0xad, 0xa0, 0x05, 0x76, 0x18, 0x1a, 0xbb, 0xc9, 0x52, 0x73, 0xe5, 0xb5, 0x7d,
0x2b, 0xd8, 0x66, 0xae, 0x38, 0x86, 0xa8, 0xf7, 0xaf, 0x4d, 0x1a, 0x8c, 0x2f, 0x78, 0xa4, 0x15,
0x80, 0x92, 0x05, 0x28, 0x07, 0x40, 0xc9, 0x02, 0x94, 0x2c, 0x41, 0x39, 0x00, 0x4a, 0x96, 0xa0,
0x64, 0x09, 0xca, 0x01, 0x50, 0xb2, 0x04, 0x25, 0x2b, 0x50, 0x0e, 0x80, 0x92, 0x15, 0x28, 0x59,
0x81, 0x72, 0x00, 0x94, 0xac, 0x40, 0xc9, 0x0a, 0x94, 0x03, 0xa0, 0xe4, 0xd9, 0x8d, 0xaa, 0x12,
0x94, 0x03, 0xa0, 0x64, 0x05, 0x4a, 0x96, 0xa0, 0x1c, 0x00, 0x25, 0x4b, 0x50, 0xb2, 0x02, 0xe5,
0x00, 0x28, 0x59, 0x81, 0x92, 0x15, 0x28, 0x07, 0x40, 0xc9, 0x0a, 0x94, 0x2c, 0x41, 0x39, 0x00,
0x4a, 0x1a, 0x50, 0xff, 0xd9, 0xc4, 0x7d, 0x15, 0x4f, 0x67, 0x5c, 0xd3, 0x47, 0xa4, 0x7e, 0x21,
0x12, 0x21, 0xb1, 0x9f, 0x76, 0xc3, 0xbd, 0xbe, 0xb9, 0x0d, 0x7d, 0x93, 0xee, 0x3f, 0x83, 0x1c,
0x33, 0x12, 0xfa, 0x18, 0xfc, 0x8c, 0x1a, 0xe0, 0x6d, 0x52, 0xbb, 0x12, 0xff, 0xd2, 0x87, 0xc4,
0x55, 0xd8, 0xb5, 0x78, 0x80, 0xed, 0x70, 0xb7, 0x50, 0x9b, 0x5e, 0x66, 0x79, 0x96, 0x7e, 0x61,
0x80, 0xa0, 0x12, 0xf6, 0xb9, 0xae, 0x04, 0x40, 0xb9, 0xb4, 0x21, 0xcd, 0x01, 0x7b, 0x7b, 0xe8,
0xf9, 0x5e, 0xa1, 0xcc, 0xcf, 0x9d, 0x15, 0x79, 0xfa, 0x15, 0x69, 0xc9, 0x71, 0x21, 0xbe, 0x87,
0xb6, 0x6b, 0xe2, 0xa6, 0xcc, 0x7f, 0xf5, 0x3e, 0x23, 0x75, 0xb3, 0xe9, 0x06, 0x71, 0xd8, 0xe8,
0xa4, 0xb3, 0x45, 0x5b, 0xa4, 0xfe, 0x03, 0x1b, 0x8d, 0x5e, 0x74, 0x2c, 0xda, 0x24, 0xb5, 0xe3,
0x9f, 0xcf, 0x47, 0x1d, 0xbb, 0xf7, 0xb7, 0x4d, 0x6a, 0xa7, 0xd1, 0x42, 0xd1, 0x6f, 0x49, 0x7b,
0x6e, 0xda, 0x05, 0xd8, 0x63, 0x8f, 0xb5, 0xc3, 0x0f, 0x0b, 0x7f, 0x90, 0xf4, 0x4f, 0xb1, 0x7f,
0xce, 0xb4, 0x1c, 0xa5, 0x5a, 0x2e, 0x59, 0x6b, 0x5e, 0xc4, 0xf4, 0x88, 0xec, 0xcc, 0xb1, 0x37,
0x8b, 0xaf, 0xb6, 0xb1, 0xfc, 0xa3, 0xdb, 0xe5, 0xd0, 0xaf, 0xe6, 0xb3, 0x8d, 0x41, 0x7b, 0x5e,
0xad, 0x74, 0xbf, 0x23, 0xbb, 0xb7, 0xfd, 0x69, 0x87, 0x38, 0xbf, 0xf1, 0x25, 0x1e, 0xa3, 0xc3,
0xe0, 0x27, 0xdd, 0x23, 0xf5, 0xdf, 0xa3, 0x24, 0xe3, 0xf8, 0x24, 0xb4, 0x98, 0x09, 0x9e, 0xda,
0xdf, 0x58, 0xdd, 0x17, 0xa4, 0xb3, 0x6a, 0x7f, 0xb3, 0xbe, 0x69, 0xea, 0x1f, 0xdc, 0xac, 0x5f,
0x3f, 0x94, 0xca, 0xaf, 0xf7, 0x97, 0x45, 0xb6, 0x4f, 0xd5, 0xec, 0x55, 0xac, 0x5f, 0xff, 0x92,
0x72, 0x71, 0x49, 0x3f, 0x20, 0x75, 0x1d, 0xeb, 0x84, 0xa3, 0x5d, 0xeb, 0xf9, 0x16, 0x33, 0x21,
0xf5, 0x88, 0xab, 0xa2, 0x24, 0x92, 0x4b, 0xf4, 0x74, 0x9e, 0x6f, 0xb1, 0x3c, 0xa6, 0x5d, 0xd2,
0x78, 0x26, 0x32, 0xd8, 0x09, 0x3e, 0x54, 0x50, 0x53, 0x2c, 0xd0, 0x4f, 0xc9, 0xf6, 0x6b, 0x31,
0xe7, 0xe3, 0x68, 0x3a, 0x95, 0x5c, 0x29, 0x7c, 0xaf, 0x40, 0xd0, 0x86, 0xd5, 0x23, 0xb3, 0x78,
0xdc, 0x20, 0xf5, 0x2c, 0x8d, 0x45, 0xda, 0x7b, 0x48, 0x6a, 0x8c, 0x47, 0x49, 0xf5, 0xf9, 0x16,
0xbe, 0x2c, 0x26, 0x78, 0xd4, 0x6c, 0x4e, 0x3b, 0xd7, 0xd7, 0xd7, 0xd7, 0x76, 0xef, 0x0a, 0xfe,
0x23, 0x7c, 0xc9, 0x5b, 0x7a, 0x40, 0x5a, 0xf1, 0x3c, 0x9a, 0xc5, 0x29, 0xec, 0xcc, 0xc8, 0xab,
0x85, 0xaa, 0x24, 0x3c, 0x21, 0xbb, 0x92, 0x47, 0xc9, 0x98, 0xbf, 0xd5, 0x3c, 0x55, 0xb1, 0x48,
0xe9, 0x76, 0xd5, 0x52, 0x51, 0xe2, 0xfd, 0x71, 0xbb, 0x27, 0x73, 0x7b, 0xb6, 0x03, 0x45, 0xa3,
0xa2, 0xa6, 0xf7, 0x7f, 0x8d, 0x90, 0x9f, 0x52, 0x71, 0x95, 0xbe, 0x5c, 0x2e, 0xb8, 0xa2, 0x0f,
0x88, 0x1d, 0xa5, 0xde, 0x2e, 0x96, 0xee, 0xf5, 0xcd, 0x28, 0xe8, 0x17, 0xa3, 0xa0, 0x7f, 0x94,
0x2e, 0x99, 0x1d, 0xa5, 0xf4, 0x4b, 0xe2, 0x4c, 0x33, 0x73, 0x4b, 0xdb, 0xe1, 0xfe, 0x9a, 0xec,
0x24, 0x1f, 0x48, 0x0c, 0x54, 0xf4, 0x73, 0x62, 0x2b, 0xed, 0x6d, 0xa3, 0xf6, 0xfe, 0x9a, 0xf6,
0x0c, 0x87, 0x13, 0xb3, 0x15, 0xdc, 0x7e, 0x5b, 0xab, 0xfc, 0x7c, 0xbb, 0x6b, 0xc2, 0x97, 0xc5,
0x9c, 0x62, 0xb6, 0x56, 0xb4, 0x4f, 0x9c, 0xe9, 0x24, 0xc1, 0xd3, 0x69, 0x87, 0x07, 0xeb, 0x3b,
0xc0, 0xe7, 0xe8, 0x57, 0x80, 0xcc, 0x40, 0x48, 0x1f, 0x13, 0xe7, 0x32, 0xd1, 0x78, 0x58, 0x70,
0x35, 0x56, 0xf5, 0xf8, 0xb0, 0xe5, 0xf2, 0xcb, 0x44, 0x83, 0x3c, 0xce, 0x07, 0xce, 0x5d, 0x72,
0x6c, 0xf6, 0x5c, 0x1e, 0x0f, 0x07, 0xb0, 0x9b, 0x6c, 0x38, 0xc0, 0x21, 0x74, 0xd7, 0x6e, 0xce,
0x6f, 0xea, 0xb3, 0xe1, 0x00, 0xed, 0x0f, 0x43, 0x9c, 0x4c, 0x1b, 0xec, 0x0f, 0xc3, 0xc2, 0xfe,
0x30, 0x44, 0xfb, 0xc3, 0x10, 0xc7, 0xd5, 0x26, 0xfb, 0x52, 0x9f, 0xa1, 0xbe, 0x86, 0xc3, 0xa6,
0xb5, 0x01, 0x25, 0xdc, 0x36, 0x23, 0x47, 0x1d, 0xf8, 0xc3, 0xbb, 0x41, 0x36, 0xf8, 0x9b, 0x07,
0x3c, 0xf7, 0x57, 0x5a, 0xd2, 0xaf, 0x49, 0xbd, 0x9a, 0x78, 0x77, 0x7d, 0x00, 0x3e, 0xec, 0xa6,
0xc0, 0x28, 0x9f, 0xfa, 0xa4, 0x96, 0x46, 0x73, 0xbe, 0xd2, 0xa2, 0x7f, 0xe2, 0x5b, 0x80, 0x99,
0x77, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7e, 0xe7, 0x47, 0x52, 0x0e, 0x09, 0x00, 0x00,
}

View File

@@ -1075,10 +1075,17 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error {
func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
exts := structPointer_Extensions(base, p.field)
if err := encodeExtensions(exts); err != nil {
v, mu := exts.extensionsRead()
if v == nil {
return nil
}
mu.Lock()
defer mu.Unlock()
if err := encodeExtensionsMap(v); err != nil {
return err
}
v, _ := exts.extensionsRead()
return o.enc_map_body(v)
}

View File

@@ -154,6 +154,7 @@ type ExtensionDesc struct {
Field int32 // field number
Name string // fully-qualified name of extension, for text formatting
Tag string // protobuf tag style
Filename string // name of the file in which the extension is defined
}
func (ed *ExtensionDesc) repeated() bool {

View File

@@ -40,6 +40,7 @@ import (
"github.com/golang/protobuf/proto"
pb "github.com/golang/protobuf/proto/testdata"
"golang.org/x/sync/errgroup"
)
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
@@ -506,3 +507,30 @@ func TestClearAllExtensions(t *testing.T) {
t.Errorf("proto.HasExtension(%s): got true, want false", proto.MarshalTextString(m))
}
}
func TestMarshalRace(t *testing.T) {
// unregistered extension
desc := &proto.ExtensionDesc{
ExtendedType: (*pb.MyMessage)(nil),
ExtensionType: (*bool)(nil),
Field: 101010100,
Name: "emptyextension",
Tag: "varint,0,opt",
}
m := &pb.MyMessage{Count: proto.Int32(4)}
if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil {
t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err)
}
var g errgroup.Group
for n := 3; n > 0; n-- {
g.Go(func() error {
_, err := proto.Marshal(m)
return err
})
}
if err := g.Wait(); err != nil {
t.Fatal(err)
}
}

46
vendor/github.com/golang/protobuf/proto/map_test.go generated vendored Normal file
View File

@@ -0,0 +1,46 @@
package proto_test
import (
"fmt"
"testing"
"github.com/golang/protobuf/proto"
ppb "github.com/golang/protobuf/proto/proto3_proto"
)
func marshalled() []byte {
m := &ppb.IntMaps{}
for i := 0; i < 1000; i++ {
m.Maps = append(m.Maps, &ppb.IntMap{
Rtt: map[int32]int32{1: 2},
})
}
b, err := proto.Marshal(m)
if err != nil {
panic(fmt.Sprintf("Can't marshal %+v: %v", m, err))
}
return b
}
func BenchmarkConcurrentMapUnmarshal(b *testing.B) {
in := marshalled()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
var out ppb.IntMaps
if err := proto.Unmarshal(in, &out); err != nil {
b.Errorf("Can't unmarshal ppb.IntMaps: %v", err)
}
}
})
}
func BenchmarkSequentialMapUnmarshal(b *testing.B) {
in := marshalled()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var out ppb.IntMaps
if err := proto.Unmarshal(in, &out); err != nil {
b.Errorf("Can't unmarshal ppb.IntMaps: %v", err)
}
}
}

View File

@@ -12,6 +12,8 @@ It has these top-level messages:
Message
Nested
MessageWithMap
IntMap
IntMaps
*/
package proto3_proto
@@ -28,7 +30,9 @@ var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Message_Humour int32
@@ -65,10 +69,10 @@ type Message struct {
ResultCount int64 `protobuf:"varint,7,opt,name=result_count,json=resultCount" json:"result_count,omitempty"`
TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"`
Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"`
ShortKey []int32 `protobuf:"varint,19,rep,name=short_key,json=shortKey" json:"short_key,omitempty"`
Key []uint64 `protobuf:"varint,5,rep,packed,name=key" json:"key,omitempty"`
ShortKey []int32 `protobuf:"varint,19,rep,packed,name=short_key,json=shortKey" json:"short_key,omitempty"`
Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
RFunny []Message_Humour `protobuf:"varint,16,rep,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
RFunny []Message_Humour `protobuf:"varint,16,rep,packed,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field" json:"proto2_field,omitempty"`
Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
@@ -83,6 +87,69 @@ func (m *Message) String() string { return proto.CompactTextString(m)
func (*Message) ProtoMessage() {}
func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Message) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Message) GetHilarity() Message_Humour {
if m != nil {
return m.Hilarity
}
return Message_UNKNOWN
}
func (m *Message) GetHeightInCm() uint32 {
if m != nil {
return m.HeightInCm
}
return 0
}
func (m *Message) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func (m *Message) GetResultCount() int64 {
if m != nil {
return m.ResultCount
}
return 0
}
func (m *Message) GetTrueScotsman() bool {
if m != nil {
return m.TrueScotsman
}
return false
}
func (m *Message) GetScore() float32 {
if m != nil {
return m.Score
}
return 0
}
func (m *Message) GetKey() []uint64 {
if m != nil {
return m.Key
}
return nil
}
func (m *Message) GetShortKey() []int32 {
if m != nil {
return m.ShortKey
}
return nil
}
func (m *Message) GetNested() *Nested {
if m != nil {
return m.Nested
@@ -90,6 +157,13 @@ func (m *Message) GetNested() *Nested {
return nil
}
func (m *Message) GetRFunny() []Message_Humour {
if m != nil {
return m.RFunny
}
return nil
}
func (m *Message) GetTerrain() map[string]*Nested {
if m != nil {
return m.Terrain
@@ -149,6 +223,20 @@ func (m *Nested) String() string { return proto.CompactTextString(m)
func (*Nested) ProtoMessage() {}
func (*Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Nested) GetBunny() string {
if m != nil {
return m.Bunny
}
return ""
}
func (m *Nested) GetCute() bool {
if m != nil {
return m.Cute
}
return false
}
type MessageWithMap struct {
ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
@@ -165,55 +253,95 @@ func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
return nil
}
type IntMap struct {
Rtt map[int32]int32 `protobuf:"bytes,1,rep,name=rtt" json:"rtt,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
}
func (m *IntMap) Reset() { *m = IntMap{} }
func (m *IntMap) String() string { return proto.CompactTextString(m) }
func (*IntMap) ProtoMessage() {}
func (*IntMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *IntMap) GetRtt() map[int32]int32 {
if m != nil {
return m.Rtt
}
return nil
}
type IntMaps struct {
Maps []*IntMap `protobuf:"bytes,1,rep,name=maps" json:"maps,omitempty"`
}
func (m *IntMaps) Reset() { *m = IntMaps{} }
func (m *IntMaps) String() string { return proto.CompactTextString(m) }
func (*IntMaps) ProtoMessage() {}
func (*IntMaps) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *IntMaps) GetMaps() []*IntMap {
if m != nil {
return m.Maps
}
return nil
}
func init() {
proto.RegisterType((*Message)(nil), "proto3_proto.Message")
proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
proto.RegisterType((*IntMap)(nil), "proto3_proto.IntMap")
proto.RegisterType((*IntMaps)(nil), "proto3_proto.IntMaps")
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
}
func init() { proto.RegisterFile("proto3_proto/proto3.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 669 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x53, 0x6d, 0x6f, 0xd3, 0x3a,
0x18, 0xbd, 0x7d, 0x4f, 0x9f, 0xa4, 0x5b, 0xae, 0xb7, 0x2b, 0x79, 0xbd, 0x7c, 0x18, 0x45, 0x42,
0x13, 0x2f, 0x19, 0x14, 0x21, 0x4d, 0x08, 0x81, 0xb6, 0xb1, 0x89, 0x6a, 0x5d, 0xa9, 0xdc, 0x8d,
0x89, 0x4f, 0x51, 0xd2, 0xba, 0x6d, 0x44, 0xe3, 0x54, 0x89, 0x83, 0x94, 0xbf, 0xc3, 0x1f, 0x05,
0xbf, 0xa4, 0x5d, 0x36, 0x75, 0xf0, 0x29, 0xf6, 0x79, 0xce, 0xf1, 0xf3, 0xe4, 0xf8, 0x18, 0xf6,
0x96, 0x71, 0xc4, 0xa3, 0x37, 0xae, 0xfa, 0x1c, 0xea, 0x8d, 0xa3, 0x3e, 0xc8, 0x2a, 0x96, 0xda,
0x7b, 0xb3, 0x28, 0x9a, 0x2d, 0xa8, 0xa6, 0xf8, 0xe9, 0xf4, 0xd0, 0x63, 0x99, 0x26, 0xb6, 0x77,
0x38, 0x4d, 0xf8, 0xc4, 0xe3, 0xde, 0xa1, 0x5c, 0x68, 0xb0, 0xf3, 0xab, 0x01, 0x8d, 0x4b, 0x9a,
0x24, 0xde, 0x8c, 0x22, 0x04, 0x55, 0xe6, 0x85, 0x14, 0x97, 0xf6, 0x4b, 0x07, 0x4d, 0xa2, 0xd6,
0xe8, 0x08, 0x8c, 0x79, 0xb0, 0xf0, 0xe2, 0x80, 0x67, 0xb8, 0x2c, 0xf0, 0xad, 0xee, 0x23, 0xa7,
0xd8, 0xd0, 0xc9, 0xc5, 0xce, 0xe7, 0x34, 0x8c, 0xd2, 0x98, 0xac, 0xd9, 0x68, 0x1f, 0xac, 0x39,
0x0d, 0x66, 0x73, 0xee, 0x06, 0xcc, 0x1d, 0x87, 0xb8, 0x22, 0xd4, 0x2d, 0x02, 0x1a, 0xeb, 0xb1,
0xd3, 0x50, 0xf6, 0x93, 0xe3, 0xe0, 0xaa, 0xa8, 0x58, 0x44, 0xad, 0xd1, 0x63, 0xb0, 0x62, 0x9a,
0xa4, 0x0b, 0xee, 0x8e, 0xa3, 0x94, 0x71, 0xdc, 0x10, 0xb5, 0x0a, 0x31, 0x35, 0x76, 0x2a, 0x21,
0xf4, 0x04, 0x5a, 0x3c, 0x4e, 0xa9, 0x9b, 0x8c, 0x23, 0x9e, 0x84, 0x1e, 0xc3, 0x86, 0xe0, 0x18,
0xc4, 0x92, 0xe0, 0x28, 0xc7, 0xd0, 0x2e, 0xd4, 0x44, 0x3d, 0xa6, 0xb8, 0x29, 0x8a, 0x65, 0xa2,
0x37, 0xc8, 0x86, 0xca, 0x77, 0x9a, 0xe1, 0xda, 0x7e, 0xe5, 0xa0, 0x4a, 0xe4, 0x12, 0xfd, 0x0f,
0xcd, 0x64, 0x1e, 0xc5, 0xdc, 0x95, 0xf8, 0x8e, 0xc0, 0x6b, 0xc4, 0x50, 0xc0, 0x85, 0x28, 0xbe,
0x80, 0x3a, 0x13, 0x56, 0xd1, 0x09, 0xae, 0x8b, 0x53, 0xcc, 0xee, 0xee, 0xdd, 0x5f, 0x1f, 0xa8,
0x1a, 0xc9, 0x39, 0xe8, 0x2d, 0x34, 0x62, 0x77, 0x9a, 0x32, 0x96, 0x61, 0x5b, 0x1c, 0xf4, 0x37,
0xa7, 0xea, 0xf1, 0xb9, 0xe4, 0xa2, 0xf7, 0xd0, 0xe0, 0x34, 0x8e, 0xbd, 0x80, 0x61, 0x10, 0x32,
0xb3, 0xdb, 0xd9, 0x2c, 0xbb, 0xd2, 0xa4, 0x33, 0xc6, 0xe3, 0x8c, 0xac, 0x24, 0xe2, 0x7e, 0xf4,
0xfd, 0x77, 0xdd, 0x69, 0x40, 0x17, 0x13, 0x6c, 0xaa, 0x41, 0xff, 0x73, 0x56, 0x77, 0xed, 0x8c,
0x52, 0xff, 0x13, 0x9d, 0x7a, 0xc2, 0xbd, 0x84, 0x98, 0x9a, 0x7a, 0x2e, 0x99, 0xa8, 0xb7, 0x56,
0xfe, 0xf0, 0x16, 0x29, 0xc5, 0x2d, 0xd5, 0xfc, 0xe9, 0xe6, 0xe6, 0x43, 0xc5, 0xfc, 0x2a, 0x89,
0x7a, 0x80, 0xfc, 0x28, 0x85, 0xa0, 0x57, 0x60, 0x88, 0x98, 0xf1, 0x79, 0xc0, 0x66, 0x78, 0x2b,
0x77, 0x4a, 0xe7, 0xd0, 0x59, 0xe5, 0xd0, 0x39, 0x66, 0x19, 0x59, 0xb3, 0x84, 0x57, 0xa6, 0xb8,
0xa5, 0xcc, 0x55, 0xbb, 0x04, 0x6f, 0xab, 0xde, 0x9b, 0x45, 0x20, 0x89, 0x57, 0x8a, 0x27, 0x64,
0x90, 0xa4, 0x7e, 0xa8, 0x87, 0xc2, 0xff, 0xe6, 0xff, 0xba, 0x69, 0x62, 0x52, 0x20, 0xa2, 0xd7,
0x60, 0x8c, 0x45, 0x2e, 0x27, 0x31, 0x65, 0x18, 0xa9, 0x56, 0x0f, 0x88, 0xd6, 0xb4, 0xf6, 0x10,
0xac, 0xa2, 0xe1, 0xab, 0xe4, 0xe8, 0xa7, 0xa1, 0x92, 0xf3, 0x0c, 0x6a, 0xda, 0xb8, 0xf2, 0x1f,
0xb2, 0xa1, 0x29, 0xef, 0xca, 0x47, 0xa5, 0xf6, 0x35, 0xd8, 0xf7, 0x5d, 0xdc, 0x70, 0xea, 0xf3,
0xbb, 0xa7, 0x3e, 0x70, 0x91, 0xb7, 0xc7, 0x76, 0x3e, 0x42, 0x5d, 0x07, 0x0a, 0x99, 0xd0, 0xb8,
0x1e, 0x5c, 0x0c, 0xbe, 0xdc, 0x0c, 0xec, 0x7f, 0x90, 0x01, 0xd5, 0xe1, 0xf5, 0x60, 0x64, 0x97,
0x50, 0x0b, 0x9a, 0xa3, 0xfe, 0xf1, 0x70, 0x74, 0xd5, 0x3b, 0xbd, 0xb0, 0xcb, 0x68, 0x1b, 0xcc,
0x93, 0x5e, 0xbf, 0xef, 0x9e, 0x1c, 0xf7, 0xfa, 0x67, 0xdf, 0xec, 0x4a, 0xa7, 0x0b, 0x75, 0x3d,
0xac, 0x7c, 0x33, 0xbe, 0x8a, 0xaf, 0x9e, 0x47, 0x6f, 0xe4, 0x2b, 0x1d, 0xa7, 0x5c, 0x0f, 0x64,
0x10, 0xb5, 0xee, 0xfc, 0x2c, 0xc1, 0x56, 0xee, 0xd9, 0x4d, 0xc0, 0xe7, 0x97, 0xde, 0x12, 0x09,
0xc3, 0xfc, 0x8c, 0x53, 0x37, 0xf4, 0x96, 0x4b, 0x99, 0x83, 0x92, 0xf2, 0xf9, 0xe5, 0x46, 0x9f,
0x73, 0x8d, 0x73, 0x22, 0x04, 0x97, 0x9a, 0x9f, 0xa7, 0xca, 0xbf, 0x45, 0xda, 0x1f, 0xc0, 0xbe,
0x4f, 0x28, 0x1a, 0x66, 0x68, 0xc3, 0x76, 0x8b, 0x86, 0x59, 0x05, 0x67, 0xfc, 0xba, 0x6e, 0xfd,
0x3b, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x40, 0x3c, 0xbe, 0x3c, 0x05, 0x00, 0x00,
// 733 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x53, 0x6d, 0x6f, 0xf3, 0x34,
0x14, 0x25, 0x4d, 0x5f, 0xd2, 0x9b, 0x74, 0x0b, 0x5e, 0x91, 0xbc, 0x02, 0x52, 0x28, 0x12, 0x8a,
0x78, 0x49, 0xa1, 0xd3, 0xd0, 0x84, 0x10, 0x68, 0x1b, 0x9b, 0xa8, 0xd6, 0x95, 0xca, 0xdd, 0x98,
0xf8, 0x14, 0xa5, 0xad, 0xdb, 0x46, 0x34, 0x4e, 0x49, 0x1c, 0xa4, 0xfc, 0x1d, 0xfe, 0x28, 0x8f,
0x6c, 0xa7, 0x5d, 0x36, 0x65, 0xcf, 0xf3, 0x29, 0xf6, 0xf1, 0xb9, 0xf7, 0x9c, 0x1c, 0x5f, 0xc3,
0xe9, 0x2e, 0x89, 0x79, 0x7c, 0xe6, 0xcb, 0xcf, 0x40, 0x6d, 0x3c, 0xf9, 0x41, 0x56, 0xf9, 0xa8,
0x77, 0xba, 0x8e, 0xe3, 0xf5, 0x96, 0x2a, 0xca, 0x3c, 0x5b, 0x0d, 0x02, 0x96, 0x2b, 0x62, 0xef,
0x84, 0xd3, 0x94, 0x2f, 0x03, 0x1e, 0x0c, 0xc4, 0x42, 0x81, 0xfd, 0xff, 0x5b, 0xd0, 0xba, 0xa7,
0x69, 0x1a, 0xac, 0x29, 0x42, 0x50, 0x67, 0x41, 0x44, 0xb1, 0xe6, 0x68, 0x6e, 0x9b, 0xc8, 0x35,
0xba, 0x00, 0x63, 0x13, 0x6e, 0x83, 0x24, 0xe4, 0x39, 0xae, 0x39, 0x9a, 0x7b, 0x34, 0xfc, 0xcc,
0x2b, 0x0b, 0x7a, 0x45, 0xb1, 0xf7, 0x7b, 0x16, 0xc5, 0x59, 0x42, 0x0e, 0x6c, 0xe4, 0x80, 0xb5,
0xa1, 0xe1, 0x7a, 0xc3, 0xfd, 0x90, 0xf9, 0x8b, 0x08, 0xeb, 0x8e, 0xe6, 0x76, 0x08, 0x28, 0x6c,
0xc4, 0xae, 0x23, 0xa1, 0x27, 0xec, 0xe0, 0xba, 0xa3, 0xb9, 0x16, 0x91, 0x6b, 0xf4, 0x05, 0x58,
0x09, 0x4d, 0xb3, 0x2d, 0xf7, 0x17, 0x71, 0xc6, 0x38, 0x6e, 0x39, 0x9a, 0xab, 0x13, 0x53, 0x61,
0xd7, 0x02, 0x42, 0x5f, 0x42, 0x87, 0x27, 0x19, 0xf5, 0xd3, 0x45, 0xcc, 0xd3, 0x28, 0x60, 0xd8,
0x70, 0x34, 0xd7, 0x20, 0x96, 0x00, 0x67, 0x05, 0x86, 0xba, 0xd0, 0x48, 0x17, 0x71, 0x42, 0x71,
0xdb, 0xd1, 0xdc, 0x1a, 0x51, 0x1b, 0x64, 0x83, 0xfe, 0x37, 0xcd, 0x71, 0xc3, 0xd1, 0xdd, 0x3a,
0x11, 0x4b, 0xf4, 0x29, 0xb4, 0xd3, 0x4d, 0x9c, 0x70, 0x5f, 0xe0, 0x27, 0x8e, 0xee, 0x36, 0x88,
0x21, 0x81, 0x3b, 0x9a, 0xa3, 0x6f, 0xa1, 0xc9, 0x68, 0xca, 0xe9, 0x12, 0x37, 0x1d, 0xcd, 0x35,
0x87, 0xdd, 0x97, 0xbf, 0x3e, 0x91, 0x67, 0xa4, 0xe0, 0xa0, 0x73, 0x68, 0x25, 0xfe, 0x2a, 0x63,
0x2c, 0xc7, 0xb6, 0xa3, 0x7f, 0x30, 0xa9, 0x66, 0x72, 0x2b, 0xb8, 0xe8, 0x67, 0x68, 0x71, 0x9a,
0x24, 0x41, 0xc8, 0x30, 0x38, 0xba, 0x6b, 0x0e, 0xfb, 0xd5, 0x65, 0x0f, 0x8a, 0x74, 0xc3, 0x78,
0x92, 0x93, 0x7d, 0x09, 0xba, 0x00, 0x75, 0xff, 0x43, 0x7f, 0x15, 0xd2, 0xed, 0x12, 0x9b, 0xd2,
0xe8, 0x27, 0xde, 0xfe, 0xae, 0xbd, 0x59, 0x36, 0xff, 0x8d, 0xae, 0x82, 0x6c, 0xcb, 0x53, 0x62,
0x2a, 0xea, 0xad, 0x60, 0xa2, 0xd1, 0xa1, 0xf2, 0xdf, 0x60, 0x9b, 0x51, 0xdc, 0x91, 0xe2, 0x5f,
0x55, 0x8b, 0x4f, 0x25, 0xf3, 0x4f, 0x41, 0x54, 0x06, 0x8a, 0x56, 0x12, 0x41, 0xdf, 0x83, 0x11,
0xb0, 0x9c, 0x6f, 0x42, 0xb6, 0xc6, 0x47, 0x45, 0x52, 0x6a, 0x0e, 0xbd, 0xfd, 0x1c, 0x7a, 0x97,
0x2c, 0x27, 0x07, 0x16, 0x3a, 0x07, 0x33, 0x0a, 0x58, 0xee, 0xcb, 0x5d, 0x8a, 0x8f, 0xa5, 0x76,
0x75, 0x11, 0x08, 0xe2, 0x83, 0xe4, 0xa1, 0x73, 0x80, 0x34, 0x9b, 0x47, 0xca, 0x14, 0xfe, 0xb8,
0xf8, 0xd7, 0x2a, 0xc7, 0xa4, 0x44, 0x44, 0x3f, 0x80, 0xb1, 0xd8, 0x84, 0xdb, 0x65, 0x42, 0x19,
0x46, 0x52, 0xea, 0x8d, 0xa2, 0x03, 0xad, 0x37, 0x05, 0xab, 0x1c, 0xf8, 0x7e, 0x72, 0xd4, 0xd3,
0x90, 0x93, 0xf3, 0x35, 0x34, 0x54, 0x70, 0xb5, 0xf7, 0xcc, 0x86, 0xa2, 0xfc, 0x54, 0xbb, 0xd0,
0x7a, 0x8f, 0x60, 0xbf, 0x4e, 0xb1, 0xa2, 0xeb, 0x37, 0x2f, 0xbb, 0xbe, 0x71, 0x91, 0xcf, 0x6d,
0xfb, 0xbf, 0x42, 0x53, 0x0d, 0x14, 0x32, 0xa1, 0xf5, 0x38, 0xb9, 0x9b, 0xfc, 0xf1, 0x34, 0xb1,
0x3f, 0x42, 0x06, 0xd4, 0xa7, 0x8f, 0x93, 0x99, 0xad, 0xa1, 0x0e, 0xb4, 0x67, 0xe3, 0xcb, 0xe9,
0xec, 0x61, 0x74, 0x7d, 0x67, 0xd7, 0xd0, 0x31, 0x98, 0x57, 0xa3, 0xf1, 0xd8, 0xbf, 0xba, 0x1c,
0x8d, 0x6f, 0xfe, 0xb2, 0xf5, 0xfe, 0x10, 0x9a, 0xca, 0xac, 0x78, 0x33, 0x73, 0x39, 0xbe, 0xca,
0x8f, 0xda, 0x88, 0x57, 0xba, 0xc8, 0xb8, 0x32, 0x64, 0x10, 0xb9, 0xee, 0xff, 0xa7, 0xc1, 0x51,
0x91, 0xd9, 0x53, 0xc8, 0x37, 0xf7, 0xc1, 0x0e, 0x4d, 0xc1, 0x9a, 0xe7, 0x9c, 0xfa, 0x51, 0xb0,
0xdb, 0x89, 0x39, 0xd0, 0x64, 0xce, 0xdf, 0x55, 0xe6, 0x5c, 0xd4, 0x78, 0x57, 0x39, 0xa7, 0xf7,
0x8a, 0x5f, 0x4c, 0xd5, 0xfc, 0x19, 0xe9, 0xfd, 0x02, 0xf6, 0x6b, 0x42, 0x39, 0x30, 0x43, 0x05,
0xd6, 0x2d, 0x07, 0x66, 0x95, 0x93, 0xf9, 0x07, 0x9a, 0x23, 0xc6, 0x85, 0xb7, 0x01, 0xe8, 0x09,
0xe7, 0x85, 0xa5, 0xcf, 0x5f, 0x5a, 0x52, 0x14, 0x8f, 0x70, 0xae, 0x2c, 0x08, 0x66, 0xef, 0x47,
0x30, 0xf6, 0x40, 0x59, 0xb2, 0x51, 0x21, 0xd9, 0x28, 0x4b, 0x9e, 0x41, 0x4b, 0xf5, 0x4b, 0x91,
0x0b, 0xf5, 0x28, 0xd8, 0xa5, 0x85, 0x68, 0xb7, 0x4a, 0x94, 0x48, 0xc6, 0xbc, 0xa9, 0x8e, 0xde,
0x05, 0x00, 0x00, 0xff, 0xff, 0x75, 0x38, 0xad, 0x84, 0xe4, 0x05, 0x00, 0x00,
}

View File

@@ -76,3 +76,12 @@ message Nested {
message MessageWithMap {
map<bool, bytes> byte_mapping = 1;
}
message IntMap {
map<int32, int32> rtt = 1;
}
message IntMaps {
repeated IntMap maps = 1;
}

View File

@@ -93,6 +93,16 @@ func TestRoundTripProto3(t *testing.T) {
}
}
func TestGettersForBasicTypesExist(t *testing.T) {
var m pb.Message
if got := m.GetNested().GetBunny(); got != "" {
t.Errorf("m.GetNested().GetBunny() = %q, want empty string", got)
}
if got := m.GetNested().GetCute(); got {
t.Errorf("m.GetNested().GetCute() = %t, want false", got)
}
}
func TestProto3SetDefaults(t *testing.T) {
in := &pb.Message{
Terrain: map[string]*pb.Nested{

File diff suppressed because it is too large Load Diff

View File

@@ -592,7 +592,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
props = oop.Prop
nv := reflect.New(oop.Type.Elem())
dst = nv.Elem().Field(0)
sv.Field(oop.Field).Set(nv)
field := sv.Field(oop.Field)
if !field.IsNil() {
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
}
field.Set(nv)
}
if !dst.IsValid() {
return p.errorf("unknown field name %q in %v", name, st)

View File

@@ -635,6 +635,17 @@ func TestOneofParsing(t *testing.T) {
if !Equal(m, want) {
t.Errorf("\n got %v\nwant %v", m, want)
}
const inOverwrite = `name:"Shrek" number:42`
m = new(Communique)
testErr := "line 1.13: field 'number' would overwrite already parsed oneof 'Union'"
if err := UnmarshalText(inOverwrite, m); err == nil {
t.Errorf("TestOneofParsing: Didn't get expected error: %v", testErr)
} else if err.Error() != testErr {
t.Errorf("TestOneofParsing: Incorrect error.\nHave: %v\nWant: %v",
err.Error(), testErr)
}
}
var benchInput string

View File

@@ -900,19 +900,8 @@ type FileOptions struct {
// generated to contain the file's getDescriptor() method as well as any
// top-level extensions defined in the file.
JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"`
// If set true, then the Java code generator will generate equals() and
// hashCode() methods for all messages defined in the .proto file.
// This increases generated code size, potentially substantially for large
// protos, which may harm a memory-constrained application.
// - In the full runtime this is a speed optimization, as the
// AbstractMessage base class includes reflection-based implementations of
// these methods.
// - In the lite runtime, setting this option changes the semantics of
// equals() and hashCode() to more closely match those of the full runtime;
// the generated methods compute their results based on field values rather
// than object identity. (Implementations should not assume that hashcodes
// will be consistent across runtimes or versions of the protocol compiler.)
JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash,def=0" json:"java_generate_equals_and_hash,omitempty"`
// This option does nothing.
JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash" json:"java_generate_equals_and_hash,omitempty"`
// If set true, then the Java2 code generator will generate code that
// throws an exception whenever an attempt is made to assign a non-UTF-8
// byte sequence to a string field.
@@ -973,7 +962,6 @@ func (*FileOptions) ExtensionRangeArray() []proto.ExtensionRange {
}
const Default_FileOptions_JavaMultipleFiles bool = false
const Default_FileOptions_JavaGenerateEqualsAndHash bool = false
const Default_FileOptions_JavaStringCheckUtf8 bool = false
const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED
const Default_FileOptions_CcGenericServices bool = false
@@ -1007,7 +995,7 @@ func (m *FileOptions) GetJavaGenerateEqualsAndHash() bool {
if m != nil && m.JavaGenerateEqualsAndHash != nil {
return *m.JavaGenerateEqualsAndHash
}
return Default_FileOptions_JavaGenerateEqualsAndHash
return false
}
func (m *FileOptions) GetJavaStringCheckUtf8() bool {
@@ -1237,7 +1225,7 @@ type FieldOptions struct {
//
//
// Note that implementations may choose not to check required fields within
// a lazy sub-message. That is, calling IsInitialized() on the outher message
// a lazy sub-message. That is, calling IsInitialized() on the outer message
// may return true even if the inner message has missing required fields.
// This is necessary because otherwise the inner message would have to be
// parsed in order to perform the check, defeating the purpose of lazy
@@ -1929,148 +1917,149 @@ func init() {
func init() { proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 2287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x59, 0xcd, 0x73, 0xdb, 0xc6,
0x15, 0x0f, 0xf8, 0x25, 0xf2, 0x91, 0xa2, 0x56, 0x2b, 0xc5, 0x86, 0xe5, 0x38, 0x96, 0x19, 0x3b,
0x96, 0xed, 0x96, 0xce, 0xc8, 0x1f, 0x71, 0x94, 0x4e, 0x3a, 0x94, 0x08, 0x2b, 0xf4, 0x50, 0x22,
0x0b, 0x4a, 0xad, 0x93, 0x1e, 0x30, 0x2b, 0x60, 0x49, 0xc1, 0x06, 0x17, 0x28, 0x00, 0xda, 0x56,
0x4e, 0x9e, 0xe9, 0xa9, 0xc7, 0xde, 0x3a, 0x6d, 0xa7, 0xd3, 0xc9, 0x25, 0x33, 0xfd, 0x03, 0x7a,
0xe8, 0xbd, 0xd7, 0xce, 0xf4, 0xde, 0x63, 0x67, 0xda, 0xff, 0xa0, 0xd7, 0xce, 0xee, 0x02, 0x20,
0xf8, 0x15, 0xab, 0x99, 0x49, 0xd2, 0x93, 0xb8, 0xbf, 0xf7, 0x7b, 0x0f, 0x6f, 0xdf, 0x3e, 0xbc,
0xf7, 0xb0, 0x82, 0xcd, 0x81, 0xeb, 0x0e, 0x1c, 0x7a, 0xd7, 0xf3, 0xdd, 0xd0, 0x3d, 0x19, 0xf5,
0xef, 0x5a, 0x34, 0x30, 0x7d, 0xdb, 0x0b, 0x5d, 0xbf, 0x2e, 0x30, 0xbc, 0x22, 0x19, 0xf5, 0x98,
0x51, 0x3b, 0x80, 0xd5, 0xc7, 0xb6, 0x43, 0x9b, 0x09, 0xb1, 0x47, 0x43, 0xfc, 0x08, 0x72, 0x7d,
0xdb, 0xa1, 0xaa, 0xb2, 0x99, 0xdd, 0x2a, 0x6f, 0x5f, 0xaf, 0x4f, 0x29, 0xd5, 0x27, 0x35, 0xba,
0x1c, 0xd6, 0x85, 0x46, 0xed, 0x9f, 0x39, 0x58, 0x9b, 0x23, 0xc5, 0x18, 0x72, 0x8c, 0x0c, 0xb9,
0x45, 0x65, 0xab, 0xa4, 0x8b, 0xdf, 0x58, 0x85, 0x25, 0x8f, 0x98, 0xcf, 0xc9, 0x80, 0xaa, 0x19,
0x01, 0xc7, 0x4b, 0xfc, 0x2e, 0x80, 0x45, 0x3d, 0xca, 0x2c, 0xca, 0xcc, 0x33, 0x35, 0xbb, 0x99,
0xdd, 0x2a, 0xe9, 0x29, 0x04, 0xdf, 0x81, 0x55, 0x6f, 0x74, 0xe2, 0xd8, 0xa6, 0x91, 0xa2, 0xc1,
0x66, 0x76, 0x2b, 0xaf, 0x23, 0x29, 0x68, 0x8e, 0xc9, 0x37, 0x61, 0xe5, 0x25, 0x25, 0xcf, 0xd3,
0xd4, 0xb2, 0xa0, 0x56, 0x39, 0x9c, 0x22, 0xee, 0x41, 0x65, 0x48, 0x83, 0x80, 0x0c, 0xa8, 0x11,
0x9e, 0x79, 0x54, 0xcd, 0x89, 0xdd, 0x6f, 0xce, 0xec, 0x7e, 0x7a, 0xe7, 0xe5, 0x48, 0xeb, 0xe8,
0xcc, 0xa3, 0xb8, 0x01, 0x25, 0xca, 0x46, 0x43, 0x69, 0x21, 0xbf, 0x20, 0x7e, 0x1a, 0x1b, 0x0d,
0xa7, 0xad, 0x14, 0xb9, 0x5a, 0x64, 0x62, 0x29, 0xa0, 0xfe, 0x0b, 0xdb, 0xa4, 0x6a, 0x41, 0x18,
0xb8, 0x39, 0x63, 0xa0, 0x27, 0xe5, 0xd3, 0x36, 0x62, 0x3d, 0xbc, 0x07, 0x25, 0xfa, 0x2a, 0xa4,
0x2c, 0xb0, 0x5d, 0xa6, 0x2e, 0x09, 0x23, 0x37, 0xe6, 0x9c, 0x22, 0x75, 0xac, 0x69, 0x13, 0x63,
0x3d, 0xfc, 0x10, 0x96, 0x5c, 0x2f, 0xb4, 0x5d, 0x16, 0xa8, 0xc5, 0x4d, 0x65, 0xab, 0xbc, 0xfd,
0xce, 0xdc, 0x44, 0xe8, 0x48, 0x8e, 0x1e, 0x93, 0x71, 0x0b, 0x50, 0xe0, 0x8e, 0x7c, 0x93, 0x1a,
0xa6, 0x6b, 0x51, 0xc3, 0x66, 0x7d, 0x57, 0x2d, 0x09, 0x03, 0x57, 0x67, 0x37, 0x22, 0x88, 0x7b,
0xae, 0x45, 0x5b, 0xac, 0xef, 0xea, 0xd5, 0x60, 0x62, 0x8d, 0x2f, 0x40, 0x21, 0x38, 0x63, 0x21,
0x79, 0xa5, 0x56, 0x44, 0x86, 0x44, 0xab, 0xda, 0x7f, 0xf2, 0xb0, 0x72, 0x9e, 0x14, 0xfb, 0x18,
0xf2, 0x7d, 0xbe, 0x4b, 0x35, 0xf3, 0xbf, 0xc4, 0x40, 0xea, 0x4c, 0x06, 0xb1, 0xf0, 0x0d, 0x83,
0xd8, 0x80, 0x32, 0xa3, 0x41, 0x48, 0x2d, 0x99, 0x11, 0xd9, 0x73, 0xe6, 0x14, 0x48, 0xa5, 0xd9,
0x94, 0xca, 0x7d, 0xa3, 0x94, 0x7a, 0x0a, 0x2b, 0x89, 0x4b, 0x86, 0x4f, 0xd8, 0x20, 0xce, 0xcd,
0xbb, 0x6f, 0xf2, 0xa4, 0xae, 0xc5, 0x7a, 0x3a, 0x57, 0xd3, 0xab, 0x74, 0x62, 0x8d, 0x9b, 0x00,
0x2e, 0xa3, 0x6e, 0xdf, 0xb0, 0xa8, 0xe9, 0xa8, 0xc5, 0x05, 0x51, 0xea, 0x70, 0xca, 0x4c, 0x94,
0x5c, 0x89, 0x9a, 0x0e, 0xfe, 0x68, 0x9c, 0x6a, 0x4b, 0x0b, 0x32, 0xe5, 0x40, 0xbe, 0x64, 0x33,
0xd9, 0x76, 0x0c, 0x55, 0x9f, 0xf2, 0xbc, 0xa7, 0x56, 0xb4, 0xb3, 0x92, 0x70, 0xa2, 0xfe, 0xc6,
0x9d, 0xe9, 0x91, 0x9a, 0xdc, 0xd8, 0xb2, 0x9f, 0x5e, 0xe2, 0xf7, 0x20, 0x01, 0x0c, 0x91, 0x56,
0x20, 0xaa, 0x50, 0x25, 0x06, 0x0f, 0xc9, 0x90, 0x6e, 0x3c, 0x82, 0xea, 0x64, 0x78, 0xf0, 0x3a,
0xe4, 0x83, 0x90, 0xf8, 0xa1, 0xc8, 0xc2, 0xbc, 0x2e, 0x17, 0x18, 0x41, 0x96, 0x32, 0x4b, 0x54,
0xb9, 0xbc, 0xce, 0x7f, 0x6e, 0x7c, 0x08, 0xcb, 0x13, 0x8f, 0x3f, 0xaf, 0x62, 0xed, 0x37, 0x05,
0x58, 0x9f, 0x97, 0x73, 0x73, 0xd3, 0xff, 0x02, 0x14, 0xd8, 0x68, 0x78, 0x42, 0x7d, 0x35, 0x2b,
0x2c, 0x44, 0x2b, 0xdc, 0x80, 0xbc, 0x43, 0x4e, 0xa8, 0xa3, 0xe6, 0x36, 0x95, 0xad, 0xea, 0xf6,
0x9d, 0x73, 0x65, 0x75, 0xbd, 0xcd, 0x55, 0x74, 0xa9, 0x89, 0x3f, 0x81, 0x5c, 0x54, 0xe2, 0xb8,
0x85, 0xdb, 0xe7, 0xb3, 0xc0, 0x73, 0x51, 0x17, 0x7a, 0xf8, 0x32, 0x94, 0xf8, 0x5f, 0x19, 0xdb,
0x82, 0xf0, 0xb9, 0xc8, 0x01, 0x1e, 0x57, 0xbc, 0x01, 0x45, 0x91, 0x66, 0x16, 0x8d, 0x5b, 0x43,
0xb2, 0xe6, 0x07, 0x63, 0xd1, 0x3e, 0x19, 0x39, 0xa1, 0xf1, 0x82, 0x38, 0x23, 0x2a, 0x12, 0xa6,
0xa4, 0x57, 0x22, 0xf0, 0xa7, 0x1c, 0xc3, 0x57, 0xa1, 0x2c, 0xb3, 0xd2, 0x66, 0x16, 0x7d, 0x25,
0xaa, 0x4f, 0x5e, 0x97, 0x89, 0xda, 0xe2, 0x08, 0x7f, 0xfc, 0xb3, 0xc0, 0x65, 0xf1, 0xd1, 0x8a,
0x47, 0x70, 0x40, 0x3c, 0xfe, 0xc3, 0xe9, 0xc2, 0x77, 0x65, 0xfe, 0xf6, 0xa6, 0x73, 0xb1, 0xf6,
0xe7, 0x0c, 0xe4, 0xc4, 0xfb, 0xb6, 0x02, 0xe5, 0xa3, 0xcf, 0xba, 0x9a, 0xd1, 0xec, 0x1c, 0xef,
0xb6, 0x35, 0xa4, 0xe0, 0x2a, 0x80, 0x00, 0x1e, 0xb7, 0x3b, 0x8d, 0x23, 0x94, 0x49, 0xd6, 0xad,
0xc3, 0xa3, 0x87, 0xf7, 0x51, 0x36, 0x51, 0x38, 0x96, 0x40, 0x2e, 0x4d, 0xb8, 0xb7, 0x8d, 0xf2,
0x18, 0x41, 0x45, 0x1a, 0x68, 0x3d, 0xd5, 0x9a, 0x0f, 0xef, 0xa3, 0xc2, 0x24, 0x72, 0x6f, 0x1b,
0x2d, 0xe1, 0x65, 0x28, 0x09, 0x64, 0xb7, 0xd3, 0x69, 0xa3, 0x62, 0x62, 0xb3, 0x77, 0xa4, 0xb7,
0x0e, 0xf7, 0x51, 0x29, 0xb1, 0xb9, 0xaf, 0x77, 0x8e, 0xbb, 0x08, 0x12, 0x0b, 0x07, 0x5a, 0xaf,
0xd7, 0xd8, 0xd7, 0x50, 0x39, 0x61, 0xec, 0x7e, 0x76, 0xa4, 0xf5, 0x50, 0x65, 0xc2, 0xad, 0x7b,
0xdb, 0x68, 0x39, 0x79, 0x84, 0x76, 0x78, 0x7c, 0x80, 0xaa, 0x78, 0x15, 0x96, 0xe5, 0x23, 0x62,
0x27, 0x56, 0xa6, 0xa0, 0x87, 0xf7, 0x11, 0x1a, 0x3b, 0x22, 0xad, 0xac, 0x4e, 0x00, 0x0f, 0xef,
0x23, 0x5c, 0xdb, 0x83, 0xbc, 0xc8, 0x2e, 0x8c, 0xa1, 0xda, 0x6e, 0xec, 0x6a, 0x6d, 0xa3, 0xd3,
0x3d, 0x6a, 0x75, 0x0e, 0x1b, 0x6d, 0xa4, 0x8c, 0x31, 0x5d, 0xfb, 0xc9, 0x71, 0x4b, 0xd7, 0x9a,
0x28, 0x93, 0xc6, 0xba, 0x5a, 0xe3, 0x48, 0x6b, 0xa2, 0x6c, 0xcd, 0x84, 0xf5, 0x79, 0x75, 0x66,
0xee, 0x9b, 0x91, 0x3a, 0xe2, 0xcc, 0x82, 0x23, 0x16, 0xb6, 0x66, 0x8e, 0xf8, 0x4b, 0x05, 0xd6,
0xe6, 0xd4, 0xda, 0xb9, 0x0f, 0xf9, 0x31, 0xe4, 0x65, 0x8a, 0xca, 0xee, 0x73, 0x6b, 0x6e, 0xd1,
0x16, 0x09, 0x3b, 0xd3, 0x81, 0x84, 0x5e, 0xba, 0x03, 0x67, 0x17, 0x74, 0x60, 0x6e, 0x62, 0xc6,
0xc9, 0x5f, 0x2a, 0xa0, 0x2e, 0xb2, 0xfd, 0x86, 0x42, 0x91, 0x99, 0x28, 0x14, 0x1f, 0x4f, 0x3b,
0x70, 0x6d, 0xf1, 0x1e, 0x66, 0xbc, 0xf8, 0x4a, 0x81, 0x0b, 0xf3, 0x07, 0x95, 0xb9, 0x3e, 0x7c,
0x02, 0x85, 0x21, 0x0d, 0x4f, 0xdd, 0xb8, 0x59, 0xbf, 0x3f, 0xa7, 0x05, 0x70, 0xf1, 0x74, 0xac,
0x22, 0xad, 0x74, 0x0f, 0xc9, 0x2e, 0x9a, 0x36, 0xa4, 0x37, 0x33, 0x9e, 0xfe, 0x2a, 0x03, 0x6f,
0xcf, 0x35, 0x3e, 0xd7, 0xd1, 0x2b, 0x00, 0x36, 0xf3, 0x46, 0xa1, 0x6c, 0xc8, 0xb2, 0x3e, 0x95,
0x04, 0x22, 0xde, 0x7d, 0x5e, 0x7b, 0x46, 0x61, 0x22, 0xcf, 0x0a, 0x39, 0x48, 0x48, 0x10, 0x1e,
0x8d, 0x1d, 0xcd, 0x09, 0x47, 0xdf, 0x5d, 0xb0, 0xd3, 0x99, 0x5e, 0xf7, 0x01, 0x20, 0xd3, 0xb1,
0x29, 0x0b, 0x8d, 0x20, 0xf4, 0x29, 0x19, 0xda, 0x6c, 0x20, 0x0a, 0x70, 0x71, 0x27, 0xdf, 0x27,
0x4e, 0x40, 0xf5, 0x15, 0x29, 0xee, 0xc5, 0x52, 0xae, 0x21, 0xba, 0x8c, 0x9f, 0xd2, 0x28, 0x4c,
0x68, 0x48, 0x71, 0xa2, 0x51, 0xfb, 0xf5, 0x12, 0x94, 0x53, 0x63, 0x1d, 0xbe, 0x06, 0x95, 0x67,
0xe4, 0x05, 0x31, 0xe2, 0x51, 0x5d, 0x46, 0xa2, 0xcc, 0xb1, 0x6e, 0x34, 0xae, 0x7f, 0x00, 0xeb,
0x82, 0xe2, 0x8e, 0x42, 0xea, 0x1b, 0xa6, 0x43, 0x82, 0x40, 0x04, 0xad, 0x28, 0xa8, 0x98, 0xcb,
0x3a, 0x5c, 0xb4, 0x17, 0x4b, 0xf0, 0x03, 0x58, 0x13, 0x1a, 0xc3, 0x91, 0x13, 0xda, 0x9e, 0x43,
0x0d, 0xfe, 0xf1, 0x10, 0x88, 0x42, 0x9c, 0x78, 0xb6, 0xca, 0x19, 0x07, 0x11, 0x81, 0x7b, 0x14,
0xe0, 0x7d, 0xb8, 0x22, 0xd4, 0x06, 0x94, 0x51, 0x9f, 0x84, 0xd4, 0xa0, 0xbf, 0x18, 0x11, 0x27,
0x30, 0x08, 0xb3, 0x8c, 0x53, 0x12, 0x9c, 0xaa, 0xeb, 0x69, 0x03, 0x97, 0x38, 0x77, 0x3f, 0xa2,
0x6a, 0x82, 0xd9, 0x60, 0xd6, 0xa7, 0x24, 0x38, 0xc5, 0x3b, 0x70, 0x41, 0x18, 0x0a, 0x42, 0xdf,
0x66, 0x03, 0xc3, 0x3c, 0xa5, 0xe6, 0x73, 0x63, 0x14, 0xf6, 0x1f, 0xa9, 0x97, 0xd3, 0x16, 0x84,
0x93, 0x3d, 0xc1, 0xd9, 0xe3, 0x94, 0xe3, 0xb0, 0xff, 0x08, 0xf7, 0xa0, 0xc2, 0xcf, 0x63, 0x68,
0x7f, 0x41, 0x8d, 0xbe, 0xeb, 0x8b, 0xe6, 0x52, 0x9d, 0xf3, 0x72, 0xa7, 0x82, 0x58, 0xef, 0x44,
0x0a, 0x07, 0xae, 0x45, 0x77, 0xf2, 0xbd, 0xae, 0xa6, 0x35, 0xf5, 0x72, 0x6c, 0xe5, 0xb1, 0xeb,
0xf3, 0x9c, 0x1a, 0xb8, 0x49, 0x8c, 0xcb, 0x32, 0xa7, 0x06, 0x6e, 0x1c, 0xe1, 0x07, 0xb0, 0x66,
0x9a, 0x72, 0xdb, 0xb6, 0x69, 0x44, 0x53, 0x7e, 0xa0, 0xa2, 0x89, 0x78, 0x99, 0xe6, 0xbe, 0x24,
0x44, 0x69, 0x1e, 0xe0, 0x8f, 0xe0, 0xed, 0x71, 0xbc, 0xd2, 0x8a, 0xab, 0x33, 0xbb, 0x9c, 0x56,
0x7d, 0x00, 0x6b, 0xde, 0xd9, 0xac, 0x22, 0x9e, 0x78, 0xa2, 0x77, 0x36, 0xad, 0x76, 0x43, 0x7c,
0xb9, 0xf9, 0xd4, 0x24, 0x21, 0xb5, 0xd4, 0x8b, 0x69, 0x76, 0x4a, 0x80, 0xef, 0x02, 0x32, 0x4d,
0x83, 0x32, 0x72, 0xe2, 0x50, 0x83, 0xf8, 0x94, 0x91, 0x40, 0xbd, 0x9a, 0x26, 0x57, 0x4d, 0x53,
0x13, 0xd2, 0x86, 0x10, 0xe2, 0xdb, 0xb0, 0xea, 0x9e, 0x3c, 0x33, 0x65, 0x72, 0x19, 0x9e, 0x4f,
0xfb, 0xf6, 0x2b, 0xf5, 0xba, 0x08, 0xd3, 0x0a, 0x17, 0x88, 0xd4, 0xea, 0x0a, 0x18, 0xdf, 0x02,
0x64, 0x06, 0xa7, 0xc4, 0xf7, 0x44, 0x77, 0x0f, 0x3c, 0x62, 0x52, 0xf5, 0x86, 0xa4, 0x4a, 0xfc,
0x30, 0x86, 0xf1, 0x53, 0x58, 0x1f, 0x31, 0x9b, 0x85, 0xd4, 0xf7, 0x7c, 0xca, 0x87, 0x74, 0xf9,
0xa6, 0xa9, 0xff, 0x5a, 0x5a, 0x30, 0x66, 0x1f, 0xa7, 0xd9, 0xf2, 0x74, 0xf5, 0xb5, 0xd1, 0x2c,
0x58, 0xdb, 0x81, 0x4a, 0xfa, 0xd0, 0x71, 0x09, 0xe4, 0xb1, 0x23, 0x85, 0xf7, 0xd0, 0xbd, 0x4e,
0x93, 0x77, 0xbf, 0xcf, 0x35, 0x94, 0xe1, 0x5d, 0xb8, 0xdd, 0x3a, 0xd2, 0x0c, 0xfd, 0xf8, 0xf0,
0xa8, 0x75, 0xa0, 0xa1, 0xec, 0xed, 0x52, 0xf1, 0xdf, 0x4b, 0xe8, 0xf5, 0xeb, 0xd7, 0xaf, 0x33,
0x4f, 0x72, 0xc5, 0xf7, 0xd1, 0xcd, 0xda, 0x5f, 0x33, 0x50, 0x9d, 0x9c, 0x7f, 0xf1, 0x8f, 0xe0,
0x62, 0xfc, 0xb1, 0x1a, 0xd0, 0xd0, 0x78, 0x69, 0xfb, 0x22, 0x1b, 0x87, 0x44, 0x4e, 0x90, 0x49,
0x20, 0xd7, 0x23, 0x56, 0x8f, 0x86, 0x3f, 0xb3, 0x7d, 0x9e, 0x6b, 0x43, 0x12, 0xe2, 0x36, 0x5c,
0x65, 0xae, 0x11, 0x84, 0x84, 0x59, 0xc4, 0xb7, 0x8c, 0xf1, 0x35, 0x81, 0x41, 0x4c, 0x93, 0x06,
0x81, 0x2b, 0x1b, 0x41, 0x62, 0xe5, 0x1d, 0xe6, 0xf6, 0x22, 0xf2, 0xb8, 0x42, 0x36, 0x22, 0xea,
0xd4, 0xa1, 0x67, 0x17, 0x1d, 0xfa, 0x65, 0x28, 0x0d, 0x89, 0x67, 0x50, 0x16, 0xfa, 0x67, 0x62,
0x6a, 0x2b, 0xea, 0xc5, 0x21, 0xf1, 0x34, 0xbe, 0xfe, 0xf6, 0x4e, 0x22, 0x15, 0xcd, 0xda, 0x3f,
0xb2, 0x50, 0x49, 0x4f, 0x6e, 0x7c, 0x10, 0x36, 0x45, 0x95, 0x56, 0xc4, 0x4b, 0xfc, 0xde, 0xd7,
0xce, 0x79, 0xf5, 0x3d, 0x5e, 0xbe, 0x77, 0x0a, 0x72, 0x9e, 0xd2, 0xa5, 0x26, 0x6f, 0x9d, 0xfc,
0xb5, 0xa5, 0x72, 0x4a, 0x2f, 0xea, 0xd1, 0x0a, 0xef, 0x43, 0xe1, 0x59, 0x20, 0x6c, 0x17, 0x84,
0xed, 0xeb, 0x5f, 0x6f, 0xfb, 0x49, 0x4f, 0x18, 0x2f, 0x3d, 0xe9, 0x19, 0x87, 0x1d, 0xfd, 0xa0,
0xd1, 0xd6, 0x23, 0x75, 0x7c, 0x09, 0x72, 0x0e, 0xf9, 0xe2, 0x6c, 0xb2, 0xd0, 0x0b, 0xe8, 0xbc,
0x81, 0xbf, 0x04, 0xb9, 0x97, 0x94, 0x3c, 0x9f, 0x2c, 0xaf, 0x02, 0xfa, 0x16, 0x5f, 0x80, 0xbb,
0x90, 0x17, 0xf1, 0xc2, 0x00, 0x51, 0xc4, 0xd0, 0x5b, 0xb8, 0x08, 0xb9, 0xbd, 0x8e, 0xce, 0x5f,
0x02, 0x04, 0x15, 0x89, 0x1a, 0xdd, 0x96, 0xb6, 0xa7, 0xa1, 0x4c, 0xed, 0x01, 0x14, 0x64, 0x10,
0xf8, 0x0b, 0x92, 0x84, 0x01, 0xbd, 0x15, 0x2d, 0x23, 0x1b, 0x4a, 0x2c, 0x3d, 0x3e, 0xd8, 0xd5,
0x74, 0x94, 0x49, 0x1f, 0x6f, 0x00, 0x95, 0xf4, 0xd0, 0xf6, 0xdd, 0xe4, 0xd4, 0x5f, 0x14, 0x28,
0xa7, 0x86, 0x30, 0xde, 0xfe, 0x89, 0xe3, 0xb8, 0x2f, 0x0d, 0xe2, 0xd8, 0x24, 0x88, 0x92, 0x02,
0x04, 0xd4, 0xe0, 0xc8, 0x79, 0x0f, 0xed, 0x3b, 0x71, 0xfe, 0x0f, 0x0a, 0xa0, 0xe9, 0x01, 0x6e,
0xca, 0x41, 0xe5, 0x7b, 0x75, 0xf0, 0xf7, 0x0a, 0x54, 0x27, 0xa7, 0xb6, 0x29, 0xf7, 0xae, 0x7d,
0xaf, 0xee, 0xfd, 0x4e, 0x81, 0xe5, 0x89, 0x59, 0xed, 0xff, 0xca, 0xbb, 0xdf, 0x66, 0x61, 0x6d,
0x8e, 0x1e, 0x6e, 0x44, 0x43, 0xad, 0x9c, 0xb3, 0x7f, 0x78, 0x9e, 0x67, 0xd5, 0x79, 0xcf, 0xec,
0x12, 0x3f, 0x8c, 0x66, 0xe0, 0x5b, 0x80, 0x6c, 0x8b, 0xb2, 0xd0, 0xee, 0xdb, 0xd4, 0x8f, 0x3e,
0xc4, 0xe5, 0xa4, 0xbb, 0x32, 0xc6, 0xe5, 0xb7, 0xf8, 0x0f, 0x00, 0x7b, 0x6e, 0x60, 0x87, 0xf6,
0x0b, 0x6a, 0xd8, 0x2c, 0xfe, 0x6a, 0xe7, 0x93, 0x6f, 0x4e, 0x47, 0xb1, 0xa4, 0xc5, 0xc2, 0x84,
0xcd, 0xe8, 0x80, 0x4c, 0xb1, 0x79, 0xed, 0xcb, 0xea, 0x28, 0x96, 0x24, 0xec, 0x6b, 0x50, 0xb1,
0xdc, 0x11, 0x1f, 0x22, 0x24, 0x8f, 0x97, 0x5a, 0x45, 0x2f, 0x4b, 0x2c, 0xa1, 0x44, 0x53, 0xde,
0xf8, 0xba, 0xa0, 0xa2, 0x97, 0x25, 0x26, 0x29, 0x37, 0x61, 0x85, 0x0c, 0x06, 0x3e, 0x37, 0x1e,
0x1b, 0x92, 0xa3, 0x6b, 0x35, 0x81, 0x05, 0x71, 0xe3, 0x09, 0x14, 0xe3, 0x38, 0xf0, 0x6e, 0xc6,
0x23, 0x61, 0x78, 0xf2, 0xd2, 0x26, 0xb3, 0x55, 0xd2, 0x8b, 0x2c, 0x16, 0x5e, 0x83, 0x8a, 0x1d,
0x18, 0xe3, 0xdb, 0xc3, 0xcc, 0x66, 0x66, 0xab, 0xa8, 0x97, 0xed, 0x20, 0xb9, 0x2e, 0xaa, 0x7d,
0x95, 0x81, 0xea, 0xe4, 0xed, 0x27, 0x6e, 0x42, 0xd1, 0x71, 0x4d, 0x22, 0x12, 0x41, 0x5e, 0xbd,
0x6f, 0xbd, 0xe1, 0xc2, 0xb4, 0xde, 0x8e, 0xf8, 0x7a, 0xa2, 0xb9, 0xf1, 0x37, 0x05, 0x8a, 0x31,
0x8c, 0x2f, 0x40, 0xce, 0x23, 0xe1, 0xa9, 0x30, 0x97, 0xdf, 0xcd, 0x20, 0x45, 0x17, 0x6b, 0x8e,
0x07, 0x1e, 0x61, 0x22, 0x05, 0x22, 0x9c, 0xaf, 0xf9, 0xb9, 0x3a, 0x94, 0x58, 0x62, 0x28, 0x76,
0x87, 0x43, 0xca, 0xc2, 0x20, 0x3e, 0xd7, 0x08, 0xdf, 0x8b, 0x60, 0x7c, 0x07, 0x56, 0x43, 0x9f,
0xd8, 0xce, 0x04, 0x37, 0x27, 0xb8, 0x28, 0x16, 0x24, 0xe4, 0x1d, 0xb8, 0x14, 0xdb, 0xb5, 0x68,
0x48, 0xcc, 0x53, 0x6a, 0x8d, 0x95, 0x0a, 0xe2, 0x6a, 0xed, 0x62, 0x44, 0x68, 0x46, 0xf2, 0x58,
0xb7, 0xf6, 0x77, 0x05, 0x56, 0xe3, 0x31, 0xde, 0x4a, 0x82, 0x75, 0x00, 0x40, 0x18, 0x73, 0xc3,
0x74, 0xb8, 0x66, 0x53, 0x79, 0x46, 0xaf, 0xde, 0x48, 0x94, 0xf4, 0x94, 0x81, 0x8d, 0x21, 0xc0,
0x58, 0xb2, 0x30, 0x6c, 0x57, 0xa1, 0x1c, 0x5d, 0x6d, 0x8b, 0xff, 0x8f, 0xc8, 0x6f, 0x3f, 0x90,
0x10, 0x9f, 0xf7, 0xf1, 0x3a, 0xe4, 0x4f, 0xe8, 0xc0, 0x66, 0xd1, 0x85, 0x9b, 0x5c, 0xc4, 0xd7,
0x78, 0xb9, 0xe4, 0x1a, 0x6f, 0xf7, 0xe7, 0xb0, 0x66, 0xba, 0xc3, 0x69, 0x77, 0x77, 0xd1, 0xd4,
0xf7, 0x67, 0xf0, 0xa9, 0xf2, 0x39, 0x8c, 0xa7, 0xb3, 0x3f, 0x2a, 0xca, 0x97, 0x99, 0xec, 0x7e,
0x77, 0xf7, 0x4f, 0x99, 0x8d, 0x7d, 0xa9, 0xda, 0x8d, 0x77, 0xaa, 0xd3, 0xbe, 0x43, 0x4d, 0xee,
0xfd, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x05, 0x54, 0xc8, 0x7d, 0x07, 0x1a, 0x00, 0x00,
// 2295 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x59, 0x4f, 0x6f, 0x1b, 0xc7,
0x15, 0xcf, 0xf2, 0x9f, 0xc8, 0x47, 0x8a, 0x1a, 0x8d, 0x14, 0x67, 0xad, 0xfc, 0xb1, 0xcc, 0xd8,
0xb1, 0x6c, 0xb7, 0x74, 0x20, 0xff, 0x89, 0xa3, 0x14, 0x29, 0x28, 0x71, 0xad, 0xd0, 0x90, 0x44,
0x76, 0x29, 0xb5, 0x4e, 0x2e, 0x8b, 0xd1, 0xee, 0x90, 0x5a, 0x7b, 0x39, 0xbb, 0xdd, 0x5d, 0xda,
0x56, 0x4e, 0x06, 0x7a, 0xea, 0xa5, 0xe7, 0xa2, 0x2d, 0x7a, 0xc8, 0x25, 0x40, 0x3f, 0x40, 0x0f,
0xfd, 0x0a, 0x05, 0x0a, 0xf4, 0x2b, 0x14, 0x05, 0xda, 0x6f, 0xd0, 0x6b, 0x31, 0x33, 0xbb, 0xcb,
0x5d, 0xfe, 0x89, 0xd5, 0x00, 0x49, 0x7a, 0x12, 0xe7, 0xf7, 0x7e, 0xef, 0xcd, 0x9b, 0x37, 0x6f,
0xde, 0xbc, 0x1d, 0xc1, 0xe6, 0xd0, 0x75, 0x87, 0x0e, 0xbd, 0xe3, 0xf9, 0x6e, 0xe8, 0x9e, 0x8e,
0x07, 0x77, 0x2c, 0x1a, 0x98, 0xbe, 0xed, 0x85, 0xae, 0xdf, 0x14, 0x18, 0x5e, 0x91, 0x8c, 0x66,
0xcc, 0x68, 0x1c, 0xc2, 0xea, 0x23, 0xdb, 0xa1, 0xed, 0x84, 0xd8, 0xa7, 0x21, 0x7e, 0x08, 0x85,
0x81, 0xed, 0x50, 0x55, 0xd9, 0xcc, 0x6f, 0x55, 0xb7, 0xaf, 0x35, 0xa7, 0x94, 0x9a, 0x59, 0x8d,
0x1e, 0x87, 0x75, 0xa1, 0xd1, 0xf8, 0x67, 0x01, 0xd6, 0xe6, 0x48, 0x31, 0x86, 0x02, 0x23, 0x23,
0x6e, 0x51, 0xd9, 0xaa, 0xe8, 0xe2, 0x37, 0x56, 0x61, 0xc9, 0x23, 0xe6, 0x33, 0x32, 0xa4, 0x6a,
0x4e, 0xc0, 0xf1, 0x10, 0xbf, 0x07, 0x60, 0x51, 0x8f, 0x32, 0x8b, 0x32, 0xf3, 0x5c, 0xcd, 0x6f,
0xe6, 0xb7, 0x2a, 0x7a, 0x0a, 0xc1, 0xb7, 0x61, 0xd5, 0x1b, 0x9f, 0x3a, 0xb6, 0x69, 0xa4, 0x68,
0xb0, 0x99, 0xdf, 0x2a, 0xea, 0x48, 0x0a, 0xda, 0x13, 0xf2, 0x0d, 0x58, 0x79, 0x41, 0xc9, 0xb3,
0x34, 0xb5, 0x2a, 0xa8, 0x75, 0x0e, 0xa7, 0x88, 0x7b, 0x50, 0x1b, 0xd1, 0x20, 0x20, 0x43, 0x6a,
0x84, 0xe7, 0x1e, 0x55, 0x0b, 0x62, 0xf5, 0x9b, 0x33, 0xab, 0x9f, 0x5e, 0x79, 0x35, 0xd2, 0x3a,
0x3e, 0xf7, 0x28, 0x6e, 0x41, 0x85, 0xb2, 0xf1, 0x48, 0x5a, 0x28, 0x2e, 0x88, 0x9f, 0xc6, 0xc6,
0xa3, 0x69, 0x2b, 0x65, 0xae, 0x16, 0x99, 0x58, 0x0a, 0xa8, 0xff, 0xdc, 0x36, 0xa9, 0x5a, 0x12,
0x06, 0x6e, 0xcc, 0x18, 0xe8, 0x4b, 0xf9, 0xb4, 0x8d, 0x58, 0x0f, 0xef, 0x41, 0x85, 0xbe, 0x0c,
0x29, 0x0b, 0x6c, 0x97, 0xa9, 0x4b, 0xc2, 0xc8, 0xf5, 0x39, 0xbb, 0x48, 0x1d, 0x6b, 0xda, 0xc4,
0x44, 0x0f, 0x3f, 0x80, 0x25, 0xd7, 0x0b, 0x6d, 0x97, 0x05, 0x6a, 0x79, 0x53, 0xd9, 0xaa, 0x6e,
0xbf, 0x33, 0x37, 0x11, 0xba, 0x92, 0xa3, 0xc7, 0x64, 0xdc, 0x01, 0x14, 0xb8, 0x63, 0xdf, 0xa4,
0x86, 0xe9, 0x5a, 0xd4, 0xb0, 0xd9, 0xc0, 0x55, 0x2b, 0xc2, 0xc0, 0x95, 0xd9, 0x85, 0x08, 0xe2,
0x9e, 0x6b, 0xd1, 0x0e, 0x1b, 0xb8, 0x7a, 0x3d, 0xc8, 0x8c, 0xf1, 0x25, 0x28, 0x05, 0xe7, 0x2c,
0x24, 0x2f, 0xd5, 0x9a, 0xc8, 0x90, 0x68, 0xd4, 0xf8, 0x4f, 0x11, 0x56, 0x2e, 0x92, 0x62, 0x9f,
0x40, 0x71, 0xc0, 0x57, 0xa9, 0xe6, 0xfe, 0x97, 0x18, 0x48, 0x9d, 0x6c, 0x10, 0x4b, 0xdf, 0x32,
0x88, 0x2d, 0xa8, 0x32, 0x1a, 0x84, 0xd4, 0x92, 0x19, 0x91, 0xbf, 0x60, 0x4e, 0x81, 0x54, 0x9a,
0x4d, 0xa9, 0xc2, 0xb7, 0x4a, 0xa9, 0x27, 0xb0, 0x92, 0xb8, 0x64, 0xf8, 0x84, 0x0d, 0xe3, 0xdc,
0xbc, 0xf3, 0x3a, 0x4f, 0x9a, 0x5a, 0xac, 0xa7, 0x73, 0x35, 0xbd, 0x4e, 0x33, 0x63, 0xdc, 0x06,
0x70, 0x19, 0x75, 0x07, 0x86, 0x45, 0x4d, 0x47, 0x2d, 0x2f, 0x88, 0x52, 0x97, 0x53, 0x66, 0xa2,
0xe4, 0x4a, 0xd4, 0x74, 0xf0, 0xc7, 0x93, 0x54, 0x5b, 0x5a, 0x90, 0x29, 0x87, 0xf2, 0x90, 0xcd,
0x64, 0xdb, 0x09, 0xd4, 0x7d, 0xca, 0xf3, 0x9e, 0x5a, 0xd1, 0xca, 0x2a, 0xc2, 0x89, 0xe6, 0x6b,
0x57, 0xa6, 0x47, 0x6a, 0x72, 0x61, 0xcb, 0x7e, 0x7a, 0x88, 0xdf, 0x87, 0x04, 0x30, 0x44, 0x5a,
0x81, 0xa8, 0x42, 0xb5, 0x18, 0x3c, 0x22, 0x23, 0xba, 0xf1, 0x10, 0xea, 0xd9, 0xf0, 0xe0, 0x75,
0x28, 0x06, 0x21, 0xf1, 0x43, 0x91, 0x85, 0x45, 0x5d, 0x0e, 0x30, 0x82, 0x3c, 0x65, 0x96, 0xa8,
0x72, 0x45, 0x9d, 0xff, 0xdc, 0xf8, 0x08, 0x96, 0x33, 0xd3, 0x5f, 0x54, 0xb1, 0xf1, 0xdb, 0x12,
0xac, 0xcf, 0xcb, 0xb9, 0xb9, 0xe9, 0x7f, 0x09, 0x4a, 0x6c, 0x3c, 0x3a, 0xa5, 0xbe, 0x9a, 0x17,
0x16, 0xa2, 0x11, 0x6e, 0x41, 0xd1, 0x21, 0xa7, 0xd4, 0x51, 0x0b, 0x9b, 0xca, 0x56, 0x7d, 0xfb,
0xf6, 0x85, 0xb2, 0xba, 0x79, 0xc0, 0x55, 0x74, 0xa9, 0x89, 0x3f, 0x85, 0x42, 0x54, 0xe2, 0xb8,
0x85, 0x5b, 0x17, 0xb3, 0xc0, 0x73, 0x51, 0x17, 0x7a, 0xf8, 0x6d, 0xa8, 0xf0, 0xbf, 0x32, 0xb6,
0x25, 0xe1, 0x73, 0x99, 0x03, 0x3c, 0xae, 0x78, 0x03, 0xca, 0x22, 0xcd, 0x2c, 0x1a, 0x5f, 0x0d,
0xc9, 0x98, 0x6f, 0x8c, 0x45, 0x07, 0x64, 0xec, 0x84, 0xc6, 0x73, 0xe2, 0x8c, 0xa9, 0x48, 0x98,
0x8a, 0x5e, 0x8b, 0xc0, 0x9f, 0x73, 0x0c, 0x5f, 0x81, 0xaa, 0xcc, 0x4a, 0x9b, 0x59, 0xf4, 0xa5,
0xa8, 0x3e, 0x45, 0x5d, 0x26, 0x6a, 0x87, 0x23, 0x7c, 0xfa, 0xa7, 0x81, 0xcb, 0xe2, 0xad, 0x15,
0x53, 0x70, 0x40, 0x4c, 0xff, 0xd1, 0x74, 0xe1, 0x7b, 0x77, 0xfe, 0xf2, 0xa6, 0x73, 0xb1, 0xf1,
0xe7, 0x1c, 0x14, 0xc4, 0x79, 0x5b, 0x81, 0xea, 0xf1, 0xe7, 0x3d, 0xcd, 0x68, 0x77, 0x4f, 0x76,
0x0f, 0x34, 0xa4, 0xe0, 0x3a, 0x80, 0x00, 0x1e, 0x1d, 0x74, 0x5b, 0xc7, 0x28, 0x97, 0x8c, 0x3b,
0x47, 0xc7, 0x0f, 0xee, 0xa1, 0x7c, 0xa2, 0x70, 0x22, 0x81, 0x42, 0x9a, 0x70, 0x77, 0x1b, 0x15,
0x31, 0x82, 0x9a, 0x34, 0xd0, 0x79, 0xa2, 0xb5, 0x1f, 0xdc, 0x43, 0xa5, 0x2c, 0x72, 0x77, 0x1b,
0x2d, 0xe1, 0x65, 0xa8, 0x08, 0x64, 0xb7, 0xdb, 0x3d, 0x40, 0xe5, 0xc4, 0x66, 0xff, 0x58, 0xef,
0x1c, 0xed, 0xa3, 0x4a, 0x62, 0x73, 0x5f, 0xef, 0x9e, 0xf4, 0x10, 0x24, 0x16, 0x0e, 0xb5, 0x7e,
0xbf, 0xb5, 0xaf, 0xa1, 0x6a, 0xc2, 0xd8, 0xfd, 0xfc, 0x58, 0xeb, 0xa3, 0x5a, 0xc6, 0xad, 0xbb,
0xdb, 0x68, 0x39, 0x99, 0x42, 0x3b, 0x3a, 0x39, 0x44, 0x75, 0xbc, 0x0a, 0xcb, 0x72, 0x8a, 0xd8,
0x89, 0x95, 0x29, 0xe8, 0xc1, 0x3d, 0x84, 0x26, 0x8e, 0x48, 0x2b, 0xab, 0x19, 0xe0, 0xc1, 0x3d,
0x84, 0x1b, 0x7b, 0x50, 0x14, 0xd9, 0x85, 0x31, 0xd4, 0x0f, 0x5a, 0xbb, 0xda, 0x81, 0xd1, 0xed,
0x1d, 0x77, 0xba, 0x47, 0xad, 0x03, 0xa4, 0x4c, 0x30, 0x5d, 0xfb, 0xd9, 0x49, 0x47, 0xd7, 0xda,
0x28, 0x97, 0xc6, 0x7a, 0x5a, 0xeb, 0x58, 0x6b, 0xa3, 0x7c, 0xc3, 0x84, 0xf5, 0x79, 0x75, 0x66,
0xee, 0xc9, 0x48, 0x6d, 0x71, 0x6e, 0xc1, 0x16, 0x0b, 0x5b, 0x33, 0x5b, 0xfc, 0x95, 0x02, 0x6b,
0x73, 0x6a, 0xed, 0xdc, 0x49, 0x7e, 0x0a, 0x45, 0x99, 0xa2, 0xf2, 0xf6, 0xb9, 0x39, 0xb7, 0x68,
0x8b, 0x84, 0x9d, 0xb9, 0x81, 0x84, 0x5e, 0xfa, 0x06, 0xce, 0x2f, 0xb8, 0x81, 0xb9, 0x89, 0x19,
0x27, 0x7f, 0xa5, 0x80, 0xba, 0xc8, 0xf6, 0x6b, 0x0a, 0x45, 0x2e, 0x53, 0x28, 0x3e, 0x99, 0x76,
0xe0, 0xea, 0xe2, 0x35, 0xcc, 0x78, 0xf1, 0xb5, 0x02, 0x97, 0xe6, 0x37, 0x2a, 0x73, 0x7d, 0xf8,
0x14, 0x4a, 0x23, 0x1a, 0x9e, 0xb9, 0xf1, 0x65, 0xfd, 0xc1, 0x9c, 0x2b, 0x80, 0x8b, 0xa7, 0x63,
0x15, 0x69, 0xa5, 0xef, 0x90, 0xfc, 0xa2, 0x6e, 0x43, 0x7a, 0x33, 0xe3, 0xe9, 0xaf, 0x73, 0xf0,
0xe6, 0x5c, 0xe3, 0x73, 0x1d, 0x7d, 0x17, 0xc0, 0x66, 0xde, 0x38, 0x94, 0x17, 0xb2, 0xac, 0x4f,
0x15, 0x81, 0x88, 0xb3, 0xcf, 0x6b, 0xcf, 0x38, 0x4c, 0xe4, 0x79, 0x21, 0x07, 0x09, 0x09, 0xc2,
0xc3, 0x89, 0xa3, 0x05, 0xe1, 0xe8, 0x7b, 0x0b, 0x56, 0x3a, 0x73, 0xd7, 0x7d, 0x08, 0xc8, 0x74,
0x6c, 0xca, 0x42, 0x23, 0x08, 0x7d, 0x4a, 0x46, 0x36, 0x1b, 0x8a, 0x02, 0x5c, 0xde, 0x29, 0x0e,
0x88, 0x13, 0x50, 0x7d, 0x45, 0x8a, 0xfb, 0xb1, 0x94, 0x6b, 0x88, 0x5b, 0xc6, 0x4f, 0x69, 0x94,
0x32, 0x1a, 0x52, 0x9c, 0x68, 0x34, 0x7e, 0xb3, 0x04, 0xd5, 0x54, 0x5b, 0x87, 0xaf, 0x42, 0xed,
0x29, 0x79, 0x4e, 0x8c, 0xb8, 0x55, 0x97, 0x91, 0xa8, 0x72, 0xac, 0x17, 0xb5, 0xeb, 0x1f, 0xc2,
0xba, 0xa0, 0xb8, 0xe3, 0x90, 0xfa, 0x86, 0xe9, 0x90, 0x20, 0x10, 0x41, 0x2b, 0x0b, 0x2a, 0xe6,
0xb2, 0x2e, 0x17, 0xed, 0xc5, 0x12, 0x7c, 0x1f, 0xd6, 0x84, 0xc6, 0x68, 0xec, 0x84, 0xb6, 0xe7,
0x50, 0x83, 0x7f, 0x3c, 0x04, 0xa2, 0x10, 0x27, 0x9e, 0xad, 0x72, 0xc6, 0x61, 0x44, 0xe0, 0x1e,
0x05, 0xb8, 0x0d, 0xef, 0x0a, 0xb5, 0x21, 0x65, 0xd4, 0x27, 0x21, 0x35, 0xe8, 0x2f, 0xc7, 0xc4,
0x09, 0x0c, 0xc2, 0x2c, 0xe3, 0x8c, 0x04, 0x67, 0xea, 0x3a, 0x37, 0xb0, 0x9b, 0x53, 0x15, 0xfd,
0x32, 0x27, 0xee, 0x47, 0x3c, 0x4d, 0xd0, 0x5a, 0xcc, 0xfa, 0x8c, 0x04, 0x67, 0x78, 0x07, 0x2e,
0x09, 0x2b, 0x41, 0xe8, 0xdb, 0x6c, 0x68, 0x98, 0x67, 0xd4, 0x7c, 0x66, 0x8c, 0xc3, 0xc1, 0x43,
0xf5, 0xed, 0xf4, 0xfc, 0xc2, 0xc3, 0xbe, 0xe0, 0xec, 0x71, 0xca, 0x49, 0x38, 0x78, 0x88, 0xfb,
0x50, 0xe3, 0x9b, 0x31, 0xb2, 0xbf, 0xa4, 0xc6, 0xc0, 0xf5, 0xc5, 0xcd, 0x52, 0x9f, 0x73, 0xb2,
0x53, 0x11, 0x6c, 0x76, 0x23, 0x85, 0x43, 0xd7, 0xa2, 0x3b, 0xc5, 0x7e, 0x4f, 0xd3, 0xda, 0x7a,
0x35, 0xb6, 0xf2, 0xc8, 0xf5, 0x79, 0x42, 0x0d, 0xdd, 0x24, 0xc0, 0x55, 0x99, 0x50, 0x43, 0x37,
0x0e, 0xef, 0x7d, 0x58, 0x33, 0x4d, 0xb9, 0x66, 0xdb, 0x34, 0xa2, 0x16, 0x3f, 0x50, 0x51, 0x26,
0x58, 0xa6, 0xb9, 0x2f, 0x09, 0x51, 0x8e, 0x07, 0xf8, 0x63, 0x78, 0x73, 0x12, 0xac, 0xb4, 0xe2,
0xea, 0xcc, 0x2a, 0xa7, 0x55, 0xef, 0xc3, 0x9a, 0x77, 0x3e, 0xab, 0x88, 0x33, 0x33, 0x7a, 0xe7,
0xd3, 0x6a, 0xd7, 0xc5, 0x67, 0x9b, 0x4f, 0x4d, 0x12, 0x52, 0x4b, 0x7d, 0x2b, 0xcd, 0x4e, 0x09,
0xf0, 0x1d, 0x40, 0xa6, 0x69, 0x50, 0x46, 0x4e, 0x1d, 0x6a, 0x10, 0x9f, 0x32, 0x12, 0xa8, 0x57,
0xd2, 0xe4, 0xba, 0x69, 0x6a, 0x42, 0xda, 0x12, 0x42, 0x7c, 0x0b, 0x56, 0xdd, 0xd3, 0xa7, 0xa6,
0xcc, 0x2c, 0xc3, 0xf3, 0xe9, 0xc0, 0x7e, 0xa9, 0x5e, 0x13, 0x61, 0x5a, 0xe1, 0x02, 0x91, 0x57,
0x3d, 0x01, 0xe3, 0x9b, 0x80, 0xcc, 0xe0, 0x8c, 0xf8, 0x9e, 0xb8, 0xda, 0x03, 0x8f, 0x98, 0x54,
0xbd, 0x2e, 0xa9, 0x12, 0x3f, 0x8a, 0x61, 0xfc, 0x04, 0xd6, 0xc7, 0xcc, 0x66, 0x21, 0xf5, 0x3d,
0x9f, 0xf2, 0x0e, 0x5d, 0x1e, 0x33, 0xf5, 0x5f, 0x4b, 0x0b, 0x7a, 0xec, 0x93, 0x34, 0x5b, 0xee,
0xae, 0xbe, 0x36, 0x9e, 0x05, 0x1b, 0x3b, 0x50, 0x4b, 0x6f, 0x3a, 0xae, 0x80, 0xdc, 0x76, 0xa4,
0xf0, 0x0b, 0x74, 0xaf, 0xdb, 0xe6, 0x57, 0xdf, 0x17, 0x1a, 0xca, 0xf1, 0x2b, 0xf8, 0xa0, 0x73,
0xac, 0x19, 0xfa, 0xc9, 0xd1, 0x71, 0xe7, 0x50, 0x43, 0xf9, 0x5b, 0x95, 0xf2, 0xbf, 0x97, 0xd0,
0xab, 0x57, 0xaf, 0x5e, 0xe5, 0x1e, 0x17, 0xca, 0x1f, 0xa0, 0x1b, 0x8d, 0xbf, 0xe6, 0xa0, 0x9e,
0x6d, 0x7e, 0xf1, 0x4f, 0xe0, 0xad, 0xf8, 0x4b, 0x35, 0xa0, 0xa1, 0xf1, 0xc2, 0xf6, 0x45, 0x36,
0x8e, 0x88, 0x6c, 0x1f, 0x93, 0x40, 0xae, 0x47, 0xac, 0x3e, 0x0d, 0x7f, 0x61, 0xfb, 0x3c, 0xd7,
0x46, 0x24, 0xc4, 0x07, 0x70, 0x85, 0xb9, 0x46, 0x10, 0x12, 0x66, 0x11, 0xdf, 0x32, 0x26, 0x6f,
0x04, 0x06, 0x31, 0x4d, 0x1a, 0x04, 0xae, 0xbc, 0x05, 0x12, 0x2b, 0xef, 0x30, 0xb7, 0x1f, 0x91,
0x27, 0xe5, 0xb1, 0x15, 0x51, 0xa7, 0x36, 0x3d, 0xbf, 0x68, 0xd3, 0xdf, 0x86, 0xca, 0x88, 0x78,
0x06, 0x65, 0xa1, 0x7f, 0x2e, 0x5a, 0xb6, 0xb2, 0x5e, 0x1e, 0x11, 0x4f, 0xe3, 0xe3, 0xef, 0x6e,
0x27, 0xb2, 0xd1, 0x2c, 0xa3, 0x4a, 0xe3, 0x1f, 0x79, 0xa8, 0xa5, 0x9b, 0x37, 0xde, 0x0b, 0x9b,
0xa2, 0x50, 0x2b, 0xe2, 0x28, 0xbf, 0xff, 0x8d, 0xad, 0x5e, 0x73, 0x8f, 0x57, 0xf0, 0x9d, 0x92,
0x6c, 0xa9, 0x74, 0xa9, 0xc9, 0x6f, 0x4f, 0x7e, 0x78, 0xa9, 0x6c, 0xd4, 0xcb, 0x7a, 0x34, 0xc2,
0xfb, 0x50, 0x7a, 0x1a, 0x08, 0xdb, 0x25, 0x61, 0xfb, 0xda, 0x37, 0xdb, 0x7e, 0xdc, 0x17, 0xc6,
0x2b, 0x8f, 0xfb, 0xc6, 0x51, 0x57, 0x3f, 0x6c, 0x1d, 0xe8, 0x91, 0x3a, 0xbe, 0x0c, 0x05, 0x87,
0x7c, 0x79, 0x9e, 0xad, 0xf5, 0x02, 0xba, 0x68, 0xf8, 0x2f, 0x43, 0xe1, 0x05, 0x25, 0xcf, 0xb2,
0x15, 0x56, 0x40, 0xdf, 0xe1, 0x31, 0xb8, 0x03, 0x45, 0x11, 0x2f, 0x0c, 0x10, 0x45, 0x0c, 0xbd,
0x81, 0xcb, 0x50, 0xd8, 0xeb, 0xea, 0xfc, 0x28, 0x20, 0xa8, 0x49, 0xd4, 0xe8, 0x75, 0xb4, 0x3d,
0x0d, 0xe5, 0x1a, 0xf7, 0xa1, 0x24, 0x83, 0xc0, 0x8f, 0x49, 0x12, 0x06, 0xf4, 0x46, 0x34, 0x8c,
0x6c, 0x28, 0xb1, 0xf4, 0xe4, 0x70, 0x57, 0xd3, 0x51, 0x2e, 0xbb, 0xc9, 0x05, 0x54, 0x6c, 0x04,
0x50, 0x4b, 0x77, 0x6f, 0xdf, 0x4b, 0x7e, 0x35, 0xfe, 0xa2, 0x40, 0x35, 0xd5, 0x8d, 0xf1, 0x3e,
0x80, 0x38, 0x8e, 0xfb, 0xc2, 0x20, 0x8e, 0x4d, 0x82, 0x28, 0x35, 0x40, 0x40, 0x2d, 0x8e, 0x5c,
0x74, 0xeb, 0xbe, 0x17, 0xe7, 0xff, 0xa8, 0x00, 0x9a, 0xee, 0xe4, 0xa6, 0x1c, 0x54, 0x7e, 0x50,
0x07, 0xff, 0xa0, 0x40, 0x3d, 0xdb, 0xbe, 0x4d, 0xb9, 0x77, 0xf5, 0x07, 0x75, 0xef, 0xf7, 0x0a,
0x2c, 0x67, 0x9a, 0xb6, 0xff, 0x2b, 0xef, 0x7e, 0x97, 0x87, 0xb5, 0x39, 0x7a, 0xb8, 0x15, 0x75,
0xb7, 0xb2, 0xe1, 0xfe, 0xf1, 0x45, 0xe6, 0x6a, 0xf2, 0xfb, 0xb3, 0x47, 0xfc, 0x30, 0x6a, 0x86,
0x6f, 0x02, 0xb2, 0x2d, 0xca, 0x42, 0x7b, 0x60, 0x53, 0x3f, 0xfa, 0x22, 0x97, 0x2d, 0xef, 0xca,
0x04, 0x97, 0x1f, 0xe5, 0x3f, 0x02, 0xec, 0xb9, 0x81, 0x1d, 0xda, 0xcf, 0xa9, 0x61, 0xb3, 0xf8,
0xf3, 0x9d, 0xb7, 0xc0, 0x05, 0x1d, 0xc5, 0x92, 0x0e, 0x0b, 0x13, 0x36, 0xa3, 0x43, 0x32, 0xc5,
0xe6, 0x15, 0x30, 0xaf, 0xa3, 0x58, 0x92, 0xb0, 0xaf, 0x42, 0xcd, 0x72, 0xc7, 0xbc, 0xa1, 0x90,
0x3c, 0x5e, 0x70, 0x15, 0xbd, 0x2a, 0xb1, 0x84, 0x12, 0x75, 0x7c, 0x93, 0x77, 0x83, 0x9a, 0x5e,
0x95, 0x98, 0xa4, 0xdc, 0x80, 0x15, 0x32, 0x1c, 0xfa, 0xdc, 0x78, 0x6c, 0x48, 0xf6, 0xb0, 0xf5,
0x04, 0x16, 0xc4, 0x8d, 0xc7, 0x50, 0x8e, 0xe3, 0xc0, 0x6f, 0x36, 0x1e, 0x09, 0xc3, 0x93, 0xaf,
0x37, 0xb9, 0xad, 0x8a, 0x5e, 0x66, 0xb1, 0xf0, 0x2a, 0xd4, 0xec, 0xc0, 0x98, 0x3c, 0x23, 0xe6,
0x36, 0x73, 0x5b, 0x65, 0xbd, 0x6a, 0x07, 0xc9, 0xbb, 0x51, 0xe3, 0xeb, 0x1c, 0xd4, 0xb3, 0xcf,
0xa0, 0xb8, 0x0d, 0x65, 0xc7, 0x35, 0x89, 0x48, 0x04, 0xf9, 0x06, 0xbf, 0xf5, 0x9a, 0x97, 0xd3,
0xe6, 0x41, 0xc4, 0xd7, 0x13, 0xcd, 0x8d, 0xbf, 0x29, 0x50, 0x8e, 0x61, 0x7c, 0x09, 0x0a, 0x1e,
0x09, 0xcf, 0x84, 0xb9, 0xe2, 0x6e, 0x0e, 0x29, 0xba, 0x18, 0x73, 0x3c, 0xf0, 0x08, 0x13, 0x29,
0x10, 0xe1, 0x7c, 0xcc, 0xf7, 0xd5, 0xa1, 0xc4, 0x12, 0x0d, 0xb2, 0x3b, 0x1a, 0x51, 0x16, 0x06,
0xf1, 0xbe, 0x46, 0xf8, 0x5e, 0x04, 0xe3, 0xdb, 0xb0, 0x1a, 0xfa, 0xc4, 0x76, 0x32, 0xdc, 0x82,
0xe0, 0xa2, 0x58, 0x90, 0x90, 0x77, 0xe0, 0x72, 0x6c, 0xd7, 0xa2, 0x21, 0x31, 0xcf, 0xa8, 0x35,
0x51, 0x2a, 0x89, 0x37, 0xb6, 0xb7, 0x22, 0x42, 0x3b, 0x92, 0xc7, 0xba, 0x8d, 0xbf, 0x2b, 0xb0,
0x1a, 0xb7, 0xf4, 0x56, 0x12, 0xac, 0x43, 0x00, 0xc2, 0x98, 0x1b, 0xa6, 0xc3, 0x35, 0x9b, 0xca,
0x33, 0x7a, 0xcd, 0x56, 0xa2, 0xa4, 0xa7, 0x0c, 0x6c, 0x8c, 0x00, 0x26, 0x92, 0x85, 0x61, 0xbb,
0x02, 0xd5, 0xe8, 0x8d, 0x5b, 0xfc, 0xa3, 0x44, 0x7e, 0x04, 0x82, 0x84, 0x78, 0xef, 0x8f, 0xd7,
0xa1, 0x78, 0x4a, 0x87, 0x36, 0x8b, 0x5e, 0xde, 0xe4, 0x20, 0x7e, 0xcf, 0x2b, 0x24, 0xef, 0x79,
0xbb, 0x4f, 0x60, 0xcd, 0x74, 0x47, 0xd3, 0xee, 0xee, 0xa2, 0xa9, 0x0f, 0xd1, 0xe0, 0x33, 0xe5,
0x0b, 0x98, 0x74, 0x6a, 0x5f, 0xe5, 0xf2, 0xfb, 0xbd, 0xdd, 0x3f, 0xe5, 0x36, 0xf6, 0xa5, 0x5e,
0x2f, 0x5e, 0xa6, 0x4e, 0x07, 0x0e, 0x35, 0xb9, 0xeb, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x5f,
0x1c, 0x48, 0x4f, 0x0d, 0x1a, 0x00, 0x00,
}

View File

@@ -626,7 +626,6 @@ func (g *Generator) CommandLineParameters(parameter string) {
}
}
}
if pluginList != "" {
// Amend the set of plugins.
enabled := make(map[string]bool)
@@ -1181,7 +1180,6 @@ func (g *Generator) generate(file *FileDescriptor) {
g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package")
g.P()
}
for _, td := range g.file.imp {
g.generateImported(td)
}
@@ -2078,11 +2076,6 @@ func (g *Generator) generateMessage(message *Descriptor) {
star = "*"
}
// In proto3, only generate getters for message fields and oneof fields.
if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE && !oneof {
continue
}
// Only export getter symbols for basic types,
// and for messages and enums in the same package.
// Groups are not exported.
@@ -2141,7 +2134,11 @@ func (g *Generator) generateMessage(message *Descriptor) {
continue
}
if !oneof {
g.P("if m != nil && m." + fname + " != nil {")
if message.proto3() {
g.P("if m != nil {")
} else {
g.P("if m != nil && m." + fname + " != nil {")
}
g.In()
g.P("return " + star + "m." + fname)
g.Out()
@@ -2559,6 +2556,7 @@ func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
g.P("Field: ", field.Number, ",")
g.P(`Name: "`, extName, `",`)
g.P("Tag: ", tag, ",")
g.P(`Filename: "`, g.file.GetName(), `",`)
g.Out()
g.P("}")

View File

@@ -48,7 +48,7 @@ import (
// It is incremented whenever an incompatibility between the generated code and
// the grpc package is introduced; the generated code references
// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion).
const generatedCodeVersion = 3
const generatedCodeVersion = 4
// Paths for packages used by code generated in this file,
// relative to the import_prefix of the generator.Generator.
@@ -254,7 +254,7 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P("},")
}
g.P("},")
g.P("Metadata: ", file.VarName(), ",")
g.P("Metadata: \"", file.GetName(), "\",")
g.P("}")
g.P()
}

View File

@@ -58,7 +58,7 @@ testbuild: regenerate
regenerate:
# Invoke protoc once to generate three independent .pb.go files in the same package.
protoc --go_out=. multi/multi{1,2,3}.proto
protoc --go_out=. multi/multi1.proto multi/multi2.proto multi/multi3.proto
#extension_test: extension_test.$O
# $(LD) -L. -o $@ $<

View File

@@ -0,0 +1,62 @@
// Code generated by protoc-gen-go.
// source: google/api/annotations.proto
// DO NOT EDIT!
/*
Package google_api is a generated protocol buffer package.
It is generated from these files:
google/api/annotations.proto
google/api/http.proto
It has these top-level messages:
HttpRule
CustomHttpPattern
*/
package google_api
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
var E_Http = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.MethodOptions)(nil),
ExtensionType: (*HttpRule)(nil),
Field: 72295728,
Name: "google.api.http",
Tag: "bytes,72295728,opt,name=http",
Filename: "google/api/annotations.proto",
}
func init() {
proto.RegisterExtension(E_Http)
}
func init() { proto.RegisterFile("google/api/annotations.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 169 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xcf, 0xcf, 0x4f,
0xcf, 0x49, 0xd5, 0x4f, 0x2c, 0xc8, 0xd4, 0x4f, 0xcc, 0xcb, 0xcb, 0x2f, 0x49, 0x2c, 0xc9, 0xcc,
0xcf, 0x2b, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x82, 0xc8, 0xea, 0x25, 0x16, 0x64,
0x4a, 0x89, 0x22, 0xa9, 0xcc, 0x28, 0x29, 0x29, 0x80, 0x28, 0x91, 0x52, 0x80, 0x0a, 0x83, 0x79,
0x49, 0xa5, 0x69, 0xfa, 0x29, 0xa9, 0xc5, 0xc9, 0x45, 0x99, 0x05, 0x25, 0xf9, 0x45, 0x10, 0x15,
0x56, 0xde, 0x5c, 0x2c, 0x20, 0xf5, 0x42, 0x72, 0x7a, 0x50, 0xd3, 0x60, 0x4a, 0xf5, 0x7c, 0x53,
0x4b, 0x32, 0xf2, 0x53, 0xfc, 0x0b, 0xc0, 0x56, 0x4a, 0x6c, 0x38, 0xb5, 0x47, 0x49, 0x81, 0x51,
0x83, 0xdb, 0x48, 0x44, 0x0f, 0x61, 0xad, 0x9e, 0x47, 0x49, 0x49, 0x41, 0x50, 0x69, 0x4e, 0x6a,
0x10, 0xd8, 0x10, 0x27, 0x15, 0x2e, 0xbe, 0xe4, 0xfc, 0x5c, 0x24, 0x05, 0x4e, 0x02, 0x8e, 0x08,
0x67, 0x07, 0x80, 0x4c, 0x0e, 0x60, 0x4c, 0x62, 0x03, 0x5b, 0x61, 0x0c, 0x08, 0x00, 0x00, 0xff,
0xff, 0x4f, 0xd1, 0x89, 0x83, 0xde, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,29 @@
// Copyright (c) 2015, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
import "google/api/http.proto";
import "google/protobuf/descriptor.proto";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}

View File

@@ -0,0 +1,381 @@
// Code generated by protoc-gen-go.
// source: google/api/http.proto
// DO NOT EDIT!
package google_api
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// `HttpRule` defines the mapping of an RPC method to one or more HTTP REST API
// methods. The mapping determines what portions of the request message are
// populated from the path, query parameters, or body of the HTTP request. The
// mapping is typically specified as an `google.api.http` annotation, see
// "google/api/annotations.proto" for details.
//
// The mapping consists of a mandatory field specifying a path template and an
// optional `body` field specifying what data is represented in the HTTP request
// body. The field name for the path indicates the HTTP method. Example:
//
// ```
// package google.storage.v2;
//
// import "google/api/annotations.proto";
//
// service Storage {
// rpc CreateObject(CreateObjectRequest) returns (Object) {
// option (google.api.http) {
// post: "/v2/{bucket_name=buckets/*}/objects"
// body: "object"
// };
// };
// }
// ```
//
// Here `bucket_name` and `object` bind to fields of the request message
// `CreateObjectRequest`.
//
// The rules for mapping HTTP path, query parameters, and body fields
// to the request message are as follows:
//
// 1. The `body` field specifies either `*` or a field path, or is
// omitted. If omitted, it assumes there is no HTTP body.
// 2. Leaf fields (recursive expansion of nested messages in the
// request) can be classified into three types:
// (a) Matched in the URL template.
// (b) Covered by body (if body is `*`, everything except (a) fields;
// else everything under the body field)
// (c) All other fields.
// 3. URL query parameters found in the HTTP request are mapped to (c) fields.
// 4. Any body sent with an HTTP request can contain only (b) fields.
//
// The syntax of the path template is as follows:
//
// Template = "/" Segments [ Verb ] ;
// Segments = Segment { "/" Segment } ;
// Segment = "*" | "**" | LITERAL | Variable ;
// Variable = "{" FieldPath [ "=" Segments ] "}" ;
// FieldPath = IDENT { "." IDENT } ;
// Verb = ":" LITERAL ;
//
// `*` matches a single path component, `**` zero or more path components, and
// `LITERAL` a constant. A `Variable` can match an entire path as specified
// again by a template; this nested template must not contain further variables.
// If no template is given with a variable, it matches a single path component.
// The notation `{var}` is henceforth equivalent to `{var=*}`.
//
// Use CustomHttpPattern to specify any HTTP method that is not included in the
// pattern field, such as HEAD, or "*" to leave the HTTP method unspecified for
// a given URL path rule. The wild-card rule is useful for services that provide
// content to Web (HTML) clients.
type HttpRule struct {
// Determines the URL pattern is matched by this rules. This pattern can be
// used with any of the {get|put|post|delete|patch} methods. A custom method
// can be defined using the 'custom' field.
//
// Types that are valid to be assigned to Pattern:
// *HttpRule_Get
// *HttpRule_Put
// *HttpRule_Post
// *HttpRule_Delete
// *HttpRule_Patch
// *HttpRule_Custom
Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"`
// The name of the request field whose value is mapped to the HTTP body, or
// `*` for mapping all fields not captured by the path pattern to the HTTP
// body.
Body string `protobuf:"bytes,7,opt,name=body" json:"body,omitempty"`
// Additional HTTP bindings for the selector. Nested bindings must not
// specify a selector and must not contain additional bindings.
AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings" json:"additional_bindings,omitempty"`
}
func (m *HttpRule) Reset() { *m = HttpRule{} }
func (m *HttpRule) String() string { return proto.CompactTextString(m) }
func (*HttpRule) ProtoMessage() {}
func (*HttpRule) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
type isHttpRule_Pattern interface {
isHttpRule_Pattern()
}
type HttpRule_Get struct {
Get string `protobuf:"bytes,2,opt,name=get,oneof"`
}
type HttpRule_Put struct {
Put string `protobuf:"bytes,3,opt,name=put,oneof"`
}
type HttpRule_Post struct {
Post string `protobuf:"bytes,4,opt,name=post,oneof"`
}
type HttpRule_Delete struct {
Delete string `protobuf:"bytes,5,opt,name=delete,oneof"`
}
type HttpRule_Patch struct {
Patch string `protobuf:"bytes,6,opt,name=patch,oneof"`
}
type HttpRule_Custom struct {
Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,oneof"`
}
func (*HttpRule_Get) isHttpRule_Pattern() {}
func (*HttpRule_Put) isHttpRule_Pattern() {}
func (*HttpRule_Post) isHttpRule_Pattern() {}
func (*HttpRule_Delete) isHttpRule_Pattern() {}
func (*HttpRule_Patch) isHttpRule_Pattern() {}
func (*HttpRule_Custom) isHttpRule_Pattern() {}
func (m *HttpRule) GetPattern() isHttpRule_Pattern {
if m != nil {
return m.Pattern
}
return nil
}
func (m *HttpRule) GetGet() string {
if x, ok := m.GetPattern().(*HttpRule_Get); ok {
return x.Get
}
return ""
}
func (m *HttpRule) GetPut() string {
if x, ok := m.GetPattern().(*HttpRule_Put); ok {
return x.Put
}
return ""
}
func (m *HttpRule) GetPost() string {
if x, ok := m.GetPattern().(*HttpRule_Post); ok {
return x.Post
}
return ""
}
func (m *HttpRule) GetDelete() string {
if x, ok := m.GetPattern().(*HttpRule_Delete); ok {
return x.Delete
}
return ""
}
func (m *HttpRule) GetPatch() string {
if x, ok := m.GetPattern().(*HttpRule_Patch); ok {
return x.Patch
}
return ""
}
func (m *HttpRule) GetCustom() *CustomHttpPattern {
if x, ok := m.GetPattern().(*HttpRule_Custom); ok {
return x.Custom
}
return nil
}
func (m *HttpRule) GetBody() string {
if m != nil {
return m.Body
}
return ""
}
func (m *HttpRule) GetAdditionalBindings() []*HttpRule {
if m != nil {
return m.AdditionalBindings
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*HttpRule) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _HttpRule_OneofMarshaler, _HttpRule_OneofUnmarshaler, _HttpRule_OneofSizer, []interface{}{
(*HttpRule_Get)(nil),
(*HttpRule_Put)(nil),
(*HttpRule_Post)(nil),
(*HttpRule_Delete)(nil),
(*HttpRule_Patch)(nil),
(*HttpRule_Custom)(nil),
}
}
func _HttpRule_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*HttpRule)
// pattern
switch x := m.Pattern.(type) {
case *HttpRule_Get:
b.EncodeVarint(2<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Get)
case *HttpRule_Put:
b.EncodeVarint(3<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Put)
case *HttpRule_Post:
b.EncodeVarint(4<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Post)
case *HttpRule_Delete:
b.EncodeVarint(5<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Delete)
case *HttpRule_Patch:
b.EncodeVarint(6<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Patch)
case *HttpRule_Custom:
b.EncodeVarint(8<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Custom); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("HttpRule.Pattern has unexpected type %T", x)
}
return nil
}
func _HttpRule_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*HttpRule)
switch tag {
case 2: // pattern.get
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Pattern = &HttpRule_Get{x}
return true, err
case 3: // pattern.put
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Pattern = &HttpRule_Put{x}
return true, err
case 4: // pattern.post
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Pattern = &HttpRule_Post{x}
return true, err
case 5: // pattern.delete
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Pattern = &HttpRule_Delete{x}
return true, err
case 6: // pattern.patch
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Pattern = &HttpRule_Patch{x}
return true, err
case 8: // pattern.custom
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(CustomHttpPattern)
err := b.DecodeMessage(msg)
m.Pattern = &HttpRule_Custom{msg}
return true, err
default:
return false, nil
}
}
func _HttpRule_OneofSizer(msg proto.Message) (n int) {
m := msg.(*HttpRule)
// pattern
switch x := m.Pattern.(type) {
case *HttpRule_Get:
n += proto.SizeVarint(2<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Get)))
n += len(x.Get)
case *HttpRule_Put:
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Put)))
n += len(x.Put)
case *HttpRule_Post:
n += proto.SizeVarint(4<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Post)))
n += len(x.Post)
case *HttpRule_Delete:
n += proto.SizeVarint(5<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Delete)))
n += len(x.Delete)
case *HttpRule_Patch:
n += proto.SizeVarint(6<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Patch)))
n += len(x.Patch)
case *HttpRule_Custom:
s := proto.Size(x.Custom)
n += proto.SizeVarint(8<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
// A custom pattern is used for defining custom HTTP verb.
type CustomHttpPattern struct {
// The name of this custom HTTP verb.
Kind string `protobuf:"bytes,1,opt,name=kind" json:"kind,omitempty"`
// The path matched by this custom verb.
Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
}
func (m *CustomHttpPattern) Reset() { *m = CustomHttpPattern{} }
func (m *CustomHttpPattern) String() string { return proto.CompactTextString(m) }
func (*CustomHttpPattern) ProtoMessage() {}
func (*CustomHttpPattern) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
func (m *CustomHttpPattern) GetKind() string {
if m != nil {
return m.Kind
}
return ""
}
func (m *CustomHttpPattern) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
func init() {
proto.RegisterType((*HttpRule)(nil), "google.api.HttpRule")
proto.RegisterType((*CustomHttpPattern)(nil), "google.api.CustomHttpPattern")
}
func init() { proto.RegisterFile("google/api/http.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 280 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x91, 0xc1, 0x6a, 0xbb, 0x40,
0x10, 0xc6, 0xff, 0x46, 0x63, 0xe2, 0x08, 0x7f, 0xe8, 0x36, 0x2d, 0x7b, 0x09, 0x48, 0x4e, 0x9e,
0x0c, 0xa4, 0x87, 0x1e, 0x7a, 0xb3, 0x14, 0x72, 0x0c, 0xbe, 0x40, 0x59, 0xdd, 0x45, 0x97, 0x1a,
0x77, 0x88, 0xe3, 0xa1, 0x8f, 0xd2, 0xb7, 0x2d, 0xbb, 0x6b, 0x48, 0xa0, 0xb7, 0xf9, 0x7e, 0x33,
0x7e, 0xdf, 0xb8, 0x03, 0x4f, 0xad, 0x31, 0x6d, 0xaf, 0xf6, 0x02, 0xf5, 0xbe, 0x23, 0xc2, 0x02,
0x2f, 0x86, 0x0c, 0x03, 0x8f, 0x0b, 0x81, 0x7a, 0xf7, 0xb3, 0x80, 0xf5, 0x91, 0x08, 0xab, 0xa9,
0x57, 0x8c, 0x41, 0xd8, 0x2a, 0xe2, 0x8b, 0x2c, 0xc8, 0x93, 0xe3, 0xbf, 0xca, 0x0a, 0xcb, 0x70,
0x22, 0x1e, 0x5e, 0x19, 0x4e, 0xc4, 0x36, 0x10, 0xa1, 0x19, 0x89, 0x47, 0x33, 0x74, 0x8a, 0x71,
0x88, 0xa5, 0xea, 0x15, 0x29, 0xbe, 0x9c, 0xf9, 0xac, 0xd9, 0x33, 0x2c, 0x51, 0x50, 0xd3, 0xf1,
0x78, 0x6e, 0x78, 0xc9, 0x5e, 0x21, 0x6e, 0xa6, 0x91, 0xcc, 0x99, 0xaf, 0xb3, 0x20, 0x4f, 0x0f,
0xdb, 0xe2, 0xb6, 0x59, 0xf1, 0xee, 0x3a, 0x76, 0xb7, 0x93, 0x20, 0x52, 0x97, 0xc1, 0x1a, 0xfa,
0x71, 0xc6, 0x20, 0xaa, 0x8d, 0xfc, 0xe6, 0x2b, 0xeb, 0x57, 0xb9, 0x9a, 0x7d, 0xc0, 0xa3, 0x90,
0x52, 0x93, 0x36, 0x83, 0xe8, 0x3f, 0x6b, 0x3d, 0x48, 0x3d, 0xb4, 0x23, 0x4f, 0xb3, 0x30, 0x4f,
0x0f, 0x9b, 0x7b, 0xe7, 0xeb, 0xff, 0x56, 0xec, 0xf6, 0x41, 0x39, 0xcf, 0x97, 0x09, 0xac, 0xd0,
0xe7, 0xed, 0xde, 0xe0, 0xe1, 0xcf, 0x12, 0x36, 0xfa, 0x4b, 0x0f, 0x92, 0x07, 0x3e, 0xda, 0xd6,
0x96, 0xa1, 0xa0, 0xce, 0x3f, 0x5c, 0xe5, 0xea, 0x72, 0x0b, 0xff, 0x1b, 0x73, 0xbe, 0x8b, 0x2d,
0x13, 0x67, 0x63, 0x2f, 0x70, 0x0a, 0xea, 0xd8, 0x9d, 0xe2, 0xe5, 0x37, 0x00, 0x00, 0xff, 0xff,
0x2f, 0x89, 0x57, 0x7f, 0xa3, 0x01, 0x00, 0x00,
}

Some files were not shown because too many files have changed in this diff Show More