Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / googleapis / gnostic / compiler / helpers.go
1 // Copyright 2017 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package compiler
16
17 import (
18         "fmt"
19         "gopkg.in/yaml.v2"
20         "regexp"
21         "sort"
22         "strconv"
23 )
24
25 // compiler helper functions, usually called from generated code
26
27 // UnpackMap gets a yaml.MapSlice if possible.
28 func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
29         m, ok := in.(yaml.MapSlice)
30         if ok {
31                 return m, true
32         }
33         // do we have an empty array?
34         a, ok := in.([]interface{})
35         if ok && len(a) == 0 {
36                 // if so, return an empty map
37                 return yaml.MapSlice{}, true
38         }
39         return nil, false
40 }
41
42 // SortedKeysForMap returns the sorted keys of a yaml.MapSlice.
43 func SortedKeysForMap(m yaml.MapSlice) []string {
44         keys := make([]string, 0)
45         for _, item := range m {
46                 keys = append(keys, item.Key.(string))
47         }
48         sort.Strings(keys)
49         return keys
50 }
51
52 // MapHasKey returns true if a yaml.MapSlice contains a specified key.
53 func MapHasKey(m yaml.MapSlice, key string) bool {
54         for _, item := range m {
55                 itemKey, ok := item.Key.(string)
56                 if ok && key == itemKey {
57                         return true
58                 }
59         }
60         return false
61 }
62
63 // MapValueForKey gets the value of a map value for a specified key.
64 func MapValueForKey(m yaml.MapSlice, key string) interface{} {
65         for _, item := range m {
66                 itemKey, ok := item.Key.(string)
67                 if ok && key == itemKey {
68                         return item.Value
69                 }
70         }
71         return nil
72 }
73
74 // ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible.
75 func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
76         stringArray := make([]string, 0)
77         for _, item := range interfaceArray {
78                 v, ok := item.(string)
79                 if ok {
80                         stringArray = append(stringArray, v)
81                 }
82         }
83         return stringArray
84 }
85
86 // MissingKeysInMap identifies which keys from a list of required keys are not in a map.
87 func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
88         missingKeys := make([]string, 0)
89         for _, k := range requiredKeys {
90                 if !MapHasKey(m, k) {
91                         missingKeys = append(missingKeys, k)
92                 }
93         }
94         return missingKeys
95 }
96
97 // InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.
98 func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
99         invalidKeys := make([]string, 0)
100         for _, item := range m {
101                 itemKey, ok := item.Key.(string)
102                 if ok {
103                         key := itemKey
104                         found := false
105                         // does the key match an allowed key?
106                         for _, allowedKey := range allowedKeys {
107                                 if key == allowedKey {
108                                         found = true
109                                         break
110                                 }
111                         }
112                         if !found {
113                                 // does the key match an allowed pattern?
114                                 for _, allowedPattern := range allowedPatterns {
115                                         if allowedPattern.MatchString(key) {
116                                                 found = true
117                                                 break
118                                         }
119                                 }
120                                 if !found {
121                                         invalidKeys = append(invalidKeys, key)
122                                 }
123                         }
124                 }
125         }
126         return invalidKeys
127 }
128
129 // DescribeMap describes a map (for debugging purposes).
130 func DescribeMap(in interface{}, indent string) string {
131         description := ""
132         m, ok := in.(map[string]interface{})
133         if ok {
134                 keys := make([]string, 0)
135                 for k := range m {
136                         keys = append(keys, k)
137                 }
138                 sort.Strings(keys)
139                 for _, k := range keys {
140                         v := m[k]
141                         description += fmt.Sprintf("%s%s:\n", indent, k)
142                         description += DescribeMap(v, indent+"  ")
143                 }
144                 return description
145         }
146         a, ok := in.([]interface{})
147         if ok {
148                 for i, v := range a {
149                         description += fmt.Sprintf("%s%d:\n", indent, i)
150                         description += DescribeMap(v, indent+"  ")
151                 }
152                 return description
153         }
154         description += fmt.Sprintf("%s%+v\n", indent, in)
155         return description
156 }
157
158 // PluralProperties returns the string "properties" pluralized.
159 func PluralProperties(count int) string {
160         if count == 1 {
161                 return "property"
162         }
163         return "properties"
164 }
165
166 // StringArrayContainsValue returns true if a string array contains a specified value.
167 func StringArrayContainsValue(array []string, value string) bool {
168         for _, item := range array {
169                 if item == value {
170                         return true
171                 }
172         }
173         return false
174 }
175
176 // StringArrayContainsValues returns true if a string array contains all of a list of specified values.
177 func StringArrayContainsValues(array []string, values []string) bool {
178         for _, value := range values {
179                 if !StringArrayContainsValue(array, value) {
180                         return false
181                 }
182         }
183         return true
184 }
185
186 // StringValue returns the string value of an item.
187 func StringValue(item interface{}) (value string, ok bool) {
188         value, ok = item.(string)
189         if ok {
190                 return value, ok
191         }
192         intValue, ok := item.(int)
193         if ok {
194                 return strconv.Itoa(intValue), true
195         }
196         return "", false
197 }