Merge pull request #49858 from smarterclayton/openapi_perf

Automatic merge from submit-queue (batch tested with PRs 49871, 49422, 49092, 49858, 48999)

bump(github.com/googleapis/gnostic):0c5108395e2de

Pick up performance improvements to OpenAPI serialization.

Fixes #49776
pull/6/head
Kubernetes Submit Queue 2017-08-01 23:35:55 -07:00 committed by GitHub
commit ba118b408b
18 changed files with 2099 additions and 309 deletions

6
Godeps/Godeps.json generated
View File

@ -1565,15 +1565,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/gophercloud/gophercloud",

View File

@ -168,15 +168,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",

View File

@ -392,15 +392,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/gophercloud/gophercloud",

View File

@ -160,15 +160,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/hashicorp/golang-lru",

View File

@ -176,15 +176,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",

View File

@ -180,15 +180,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/juju/ratelimit",

View File

@ -88,15 +88,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/juju/ratelimit",

View File

@ -168,15 +168,15 @@
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/compiler",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/googleapis/gnostic/extensions",
"Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5"
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",

File diff suppressed because it is too large Load Diff

View File

@ -1376,7 +1376,7 @@ func (m *ItemsItem) GetSchema() []*Schema {
}
type JsonReference struct {
XRef string `protobuf:"bytes,1,opt,name=_ref,json=ref" json:"_ref,omitempty"`
XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"`
Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"`
}
@ -2513,7 +2513,7 @@ func _ParametersItem_OneofSizer(msg proto.Message) (n int) {
}
type PathItem struct {
XRef string `protobuf:"bytes,1,opt,name=_ref,json=ref" json:"_ref,omitempty"`
XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"`
Get *Operation `protobuf:"bytes,2,opt,name=get" json:"get,omitempty"`
Put *Operation `protobuf:"bytes,3,opt,name=put" json:"put,omitempty"`
Post *Operation `protobuf:"bytes,4,opt,name=post" json:"post,omitempty"`
@ -3392,7 +3392,7 @@ func (m *Responses) GetVendorExtension() []*NamedAny {
// A deterministic version of a JSON Schema object.
type Schema struct {
XRef string `protobuf:"bytes,1,opt,name=_ref,json=ref" json:"_ref,omitempty"`
XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"`
Format string `protobuf:"bytes,2,opt,name=format" json:"format,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title" json:"title,omitempty"`
Description string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"`
@ -4351,7 +4351,7 @@ var fileDescriptor0 = []byte{
0xfe, 0x90, 0x83, 0x0c, 0x89, 0xa3, 0x14, 0x7e, 0x7d, 0x1e, 0xe1, 0xbf, 0x05, 0x4d, 0xa6, 0x0c,
0xac, 0x56, 0x77, 0x23, 0x51, 0xab, 0x2b, 0x4f, 0x2e, 0xac, 0x6c, 0xdd, 0x85, 0xd6, 0x37, 0x02,
0xe2, 0x1a, 0x78, 0x80, 0x7d, 0xec, 0xf6, 0xb0, 0xb6, 0x0c, 0x15, 0xd3, 0xc7, 0x03, 0x21, 0xe3,
0xb2, 0x8f, 0x07, 0xd3, 0xeb, 0x4f, 0x5b, 0x1e, 0xd4, 0xc5, 0x33, 0xcd, 0x58, 0x5c, 0x39, 0xf3,
0xb2, 0x81, 0x07, 0xd3, 0xeb, 0x4f, 0x5b, 0x1e, 0xd4, 0xc5, 0x33, 0xcd, 0x58, 0x5c, 0x39, 0xf3,
0x59, 0xe6, 0x1e, 0x34, 0x24, 0x50, 0xb9, 0xe5, 0x2b, 0xb2, 0xaa, 0x58, 0x52, 0x3b, 0x20, 0x0e,
0xdd, 0x7a, 0x17, 0x16, 0x12, 0x0a, 0xa8, 0xa4, 0x74, 0x2d, 0x4d, 0x29, 0x25, 0x4c, 0xa1, 0xb7,
0x82, 0xd8, 0xfb, 0xd0, 0x66, 0xc4, 0xe2, 0x22, 0x9a, 0x8a, 0xde, 0xeb, 0x69, 0x7a, 0x17, 0x94,
@ -4452,5 +4452,5 @@ var fileDescriptor0 = []byte{
0xf3, 0x70, 0x5f, 0x1c, 0xc1, 0xe5, 0xf0, 0xcc, 0x7d, 0xcc, 0xdb, 0xaf, 0x42, 0x9b, 0xf8, 0x47,
0x12, 0xd7, 0x3c, 0xd9, 0xb9, 0xbd, 0x28, 0xbe, 0x5d, 0xdd, 0xf7, 0x49, 0x48, 0xf6, 0x8b, 0xbf,
0x28, 0x95, 0xf7, 0x76, 0x0f, 0x0e, 0x6b, 0xec, 0x63, 0xd0, 0x37, 0xff, 0x19, 0x00, 0x00, 0xff,
0xff, 0x3c, 0x01, 0x3f, 0x38, 0xe4, 0x3a, 0x00, 0x00,
0xff, 0xd4, 0x0a, 0xef, 0xca, 0xe4, 0x3a, 0x00, 0x00,
}

View File

@ -14,28 +14,30 @@
package compiler
// Context contains state of the compiler as it traverses a document.
type Context struct {
Parent *Context
Name string
ExtensionHandlers *[]ExtensionHandler
}
// NewContextWithExtensions returns a new object representing the compiler state
func NewContextWithExtensions(name string, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
return &Context{Name: name, Parent: parent, ExtensionHandlers: extensionHandlers}
}
// NewContext returns a new object representing the compiler state
func NewContext(name string, parent *Context) *Context {
if parent != nil {
return &Context{Name: name, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
} else {
return &Context{Name: name, Parent: parent, ExtensionHandlers: nil}
}
return &Context{Name: name, Parent: parent, ExtensionHandlers: nil}
}
// Description returns a text description of the compiler state
func (context *Context) Description() string {
if context.Parent != nil {
return context.Parent.Description() + "." + context.Name
} else {
return context.Name
}
return context.Name
}

View File

@ -14,29 +14,31 @@
package compiler
// basic error type
// Error represents compiler errors and their location in the document.
type Error struct {
Context *Context
Message string
}
// NewError creates an Error.
func NewError(context *Context, message string) *Error {
return &Error{Context: context, Message: message}
}
// Error returns the string value of an Error.
func (err *Error) Error() string {
if err.Context != nil {
return "ERROR " + err.Context.Description() + " " + err.Message
} else {
if err.Context == nil {
return "ERROR " + err.Message
}
return "ERROR " + err.Context.Description() + " " + err.Message
}
// container for groups of errors
// ErrorGroup is a container for groups of Error values.
type ErrorGroup struct {
Errors []error
}
// NewErrorGroupOrNil returns a new ErrorGroup for a slice of errors or nil if the slice is empty.
func NewErrorGroupOrNil(errors []error) error {
if len(errors) == 0 {
return nil

View File

@ -29,16 +29,18 @@ import (
yaml "gopkg.in/yaml.v2"
)
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
type ExtensionHandler struct {
Name string
}
// HandleExtension calls a binary extension handler.
func HandleExtension(context *Context, in interface{}, extensionName string) (bool, *any.Any, error) {
handled := false
var errFromPlugin error
var outFromPlugin *any.Any
if context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 {
if context != nil && context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 {
for _, customAnyProtoGenerator := range *(context.ExtensionHandlers) {
outFromPlugin, errFromPlugin = customAnyProtoGenerator.handle(in, extensionName)
if outFromPlugin == nil {

View File

@ -19,27 +19,27 @@ import (
"gopkg.in/yaml.v2"
"regexp"
"sort"
"strings"
"strconv"
)
// compiler helper functions, usually called from generated code
// UnpackMap gets a yaml.MapSlice if possible.
func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
m, ok := in.(yaml.MapSlice)
if ok {
return m, ok
} else {
// do we have an empty array?
a, ok := in.([]interface{})
if ok && len(a) == 0 {
// if so, return an empty map
return yaml.MapSlice{}, ok
} else {
return nil, ok
}
return m, true
}
// do we have an empty array?
a, ok := in.([]interface{})
if ok && len(a) == 0 {
// if so, return an empty map
return yaml.MapSlice{}, true
}
return nil, false
}
// SortedKeysForMap returns the sorted keys of a yaml.MapSlice.
func SortedKeysForMap(m yaml.MapSlice) []string {
keys := make([]string, 0)
for _, item := range m {
@ -49,6 +49,7 @@ func SortedKeysForMap(m yaml.MapSlice) []string {
return keys
}
// MapHasKey returns true if a yaml.MapSlice contains a specified key.
func MapHasKey(m yaml.MapSlice, key string) bool {
for _, item := range m {
itemKey, ok := item.Key.(string)
@ -59,6 +60,7 @@ func MapHasKey(m yaml.MapSlice, key string) bool {
return false
}
// MapValueForKey gets the value of a map value for a specified key.
func MapValueForKey(m yaml.MapSlice, key string) interface{} {
for _, item := range m {
itemKey, ok := item.Key.(string)
@ -69,6 +71,7 @@ func MapValueForKey(m yaml.MapSlice, key string) interface{} {
return nil
}
// ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible.
func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
stringArray := make([]string, 0)
for _, item := range interfaceArray {
@ -80,22 +83,7 @@ func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
return stringArray
}
func PatternMatches(pattern string, value string) bool {
// if pattern contains a subpattern like "{path}", replace it with ".*"
if pattern[0] != '^' {
subpatternPattern := regexp.MustCompile("^.*(\\{.*\\}).*$")
if matches := subpatternPattern.FindSubmatch([]byte(pattern)); matches != nil {
match := string(matches[1])
pattern = strings.Replace(pattern, match, ".*", -1)
}
}
matched, err := regexp.Match(pattern, []byte(value))
if err != nil {
panic(err)
}
return matched
}
// MissingKeysInMap identifies which keys from a list of required keys are not in a map.
func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
missingKeys := make([]string, 0)
for _, k := range requiredKeys {
@ -106,7 +94,8 @@ func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
return missingKeys
}
func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []string) []string {
// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.
func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
invalidKeys := make([]string, 0)
for _, item := range m {
itemKey, ok := item.Key.(string)
@ -123,7 +112,7 @@ func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []s
if !found {
// does the key match an allowed pattern?
for _, allowedPattern := range allowedPatterns {
if PatternMatches(allowedPattern, key) {
if allowedPattern.MatchString(key) {
found = true
break
}
@ -137,13 +126,13 @@ func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []s
return invalidKeys
}
// describe a map (for debugging purposes)
// DescribeMap describes a map (for debugging purposes).
func DescribeMap(in interface{}, indent string) string {
description := ""
m, ok := in.(map[string]interface{})
if ok {
keys := make([]string, 0)
for k, _ := range m {
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
@ -166,14 +155,15 @@ func DescribeMap(in interface{}, indent string) string {
return description
}
// PluralProperties returns the string "properties" pluralized.
func PluralProperties(count int) string {
if count == 1 {
return "property"
} else {
return "properties"
}
return "properties"
}
// StringArrayContainsValue returns true if a string array contains a specified value.
func StringArrayContainsValue(array []string, value string) bool {
for _, item := range array {
if item == value {
@ -183,6 +173,7 @@ func StringArrayContainsValue(array []string, value string) bool {
return false
}
// StringArrayContainsValues returns true if a string array contains all of a list of specified values.
func StringArrayContainsValues(array []string, values []string) bool {
for _, value := range values {
if !StringArrayContainsValue(array, value) {
@ -191,3 +182,16 @@ func StringArrayContainsValues(array []string, values []string) bool {
}
return true
}
// StringValue returns the string value of an item.
func StringValue(item interface{}) (value string, ok bool) {
value, ok = item.(string)
if ok {
return value, ok
}
intValue, ok := item.(int)
if ok {
return strconv.Itoa(intValue), true
}
return "", false
}

View File

@ -25,29 +25,30 @@ import (
"strings"
)
var file_cache map[string][]byte
var info_cache map[string]interface{}
var fileCache map[string][]byte
var infoCache map[string]interface{}
var count int64
var VERBOSE_READER = false
var verboseReader = false
func initializeFileCache() {
if file_cache == nil {
file_cache = make(map[string][]byte, 0)
if fileCache == nil {
fileCache = make(map[string][]byte, 0)
}
}
func initializeInfoCache() {
if info_cache == nil {
info_cache = make(map[string]interface{}, 0)
if infoCache == nil {
infoCache = make(map[string]interface{}, 0)
}
}
// FetchFile gets a specified file from the local filesystem or a remote location.
func FetchFile(fileurl string) ([]byte, error) {
initializeFileCache()
bytes, ok := file_cache[fileurl]
bytes, ok := fileCache[fileurl]
if ok {
if VERBOSE_READER {
if verboseReader {
log.Printf("Cache hit %s", fileurl)
}
return bytes, nil
@ -56,30 +57,17 @@ func FetchFile(fileurl string) ([]byte, error) {
response, err := http.Get(fileurl)
if err != nil {
return nil, err
} else {
defer response.Body.Close()
bytes, err := ioutil.ReadAll(response.Body)
if err == nil {
file_cache[fileurl] = bytes
}
return bytes, err
}
defer response.Body.Close()
bytes, err = ioutil.ReadAll(response.Body)
if err == nil {
fileCache[fileurl] = bytes
}
return bytes, err
}
// read a file and unmarshal it as a yaml.MapSlice
func ReadInfoForFile(filename string) (interface{}, error) {
initializeInfoCache()
info, ok := info_cache[filename]
if ok {
if VERBOSE_READER {
log.Printf("Cache hit info for file %s", filename)
}
return info, nil
}
if VERBOSE_READER {
log.Printf("Reading info for file %s", filename)
}
// ReadBytesForFile reads the bytes of a file.
func ReadBytesForFile(filename string) ([]byte, error) {
// is the filename a url?
fileurl, _ := url.Parse(filename)
if fileurl.Scheme != "" {
@ -88,43 +76,51 @@ func ReadInfoForFile(filename string) (interface{}, error) {
if err != nil {
return nil, err
}
var info yaml.MapSlice
err = yaml.Unmarshal(bytes, &info)
if err != nil {
return nil, err
}
info_cache[filename] = info
return info, nil
} else {
// no, it's a local filename
bytes, err := ioutil.ReadFile(filename)
if err != nil {
log.Printf("File error: %v\n", err)
return nil, err
}
var info yaml.MapSlice
err = yaml.Unmarshal(bytes, &info)
if err != nil {
return nil, err
}
info_cache[filename] = info
return info, nil
return bytes, nil
}
// no, it's a local filename
bytes, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return bytes, nil
}
// read a file and return the fragment needed to resolve a $ref
// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice.
func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
initializeInfoCache()
cachedInfo, ok := infoCache[filename]
if ok {
if verboseReader {
log.Printf("Cache hit info for file %s", filename)
}
return cachedInfo, nil
}
if verboseReader {
log.Printf("Reading info for file %s", filename)
}
var info yaml.MapSlice
err := yaml.Unmarshal(bytes, &info)
if err != nil {
return nil, err
}
infoCache[filename] = info
return info, nil
}
// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref.
func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
initializeInfoCache()
{
info, ok := info_cache[ref]
info, ok := infoCache[ref]
if ok {
if VERBOSE_READER {
if verboseReader {
log.Printf("Cache hit for ref %s#%s", basefile, ref)
}
return info, nil
}
}
if VERBOSE_READER {
if verboseReader {
log.Printf("Reading info for ref %s#%s", basefile, ref)
}
count = count + 1
@ -136,7 +132,11 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
} else {
filename = basefile
}
info, err := ReadInfoForFile(filename)
bytes, err := ReadBytesForFile(filename)
if err != nil {
return nil, err
}
info, err := ReadInfoFromBytes(filename, bytes)
if err != nil {
log.Printf("File error: %v\n", err)
} else {
@ -154,7 +154,7 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
}
}
if !found {
info_cache[ref] = nil
infoCache[ref] = nil
return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref))
}
}
@ -162,6 +162,6 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
}
}
}
info_cache[ref] = info
infoCache[ref] = info
return info, nil
}

View File

@ -18,7 +18,6 @@ go_library(
"//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes/any:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
],
)

View File

@ -3,5 +3,3 @@ go get github.com/golang/protobuf/protoc-gen-go
protoc \
--go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. *.proto
go build
go install

View File

@ -21,40 +21,39 @@ import (
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"gopkg.in/yaml.v2"
)
type documentHandler func(version string, extensionName string, document string)
type extensionHandler func(name string, info yaml.MapSlice) (bool, proto.Message, error)
type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error)
func forInputYamlFromOpenapic(handler documentHandler) {
data, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Println("File error:", err.Error())
os.Exit(1)
}
if len(data) == 0 {
fmt.Println("No input data.")
os.Exit(1)
}
request := &ExtensionHandlerRequest{}
err = proto.Unmarshal(data, request)
if err != nil {
fmt.Println("Input error:", err.Error())
os.Exit(1)
}
handler(request.Wrapper.Version, request.Wrapper.ExtensionName, request.Wrapper.Yaml)
}
// ProcessExtension calles the handler for a specified extension.
func ProcessExtension(handleExtension extensionHandler) {
response := &ExtensionHandlerResponse{}
forInputYamlFromOpenapic(
func(version string, extensionName string, yamlInput string) {
var info yaml.MapSlice
var newObject proto.Message
var err error
err = yaml.Unmarshal([]byte(yamlInput), &info)
if err != nil {
response.Error = append(response.Error, err.Error())
responseBytes, _ := proto.Marshal(response)
os.Stdout.Write(responseBytes)
os.Exit(0)
}
handled, newObject, err := handleExtension(extensionName, info)
handled, newObject, err := handleExtension(extensionName, yamlInput)
if !handled {
responseBytes, _ := proto.Marshal(response)
os.Stdout.Write(responseBytes)