1 // Copyright 2017 Google Inc. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
25 // compiler helper functions, usually called from generated code
27 // UnpackMap gets a yaml.MapSlice if possible.
28 func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
29 m, ok := in.(yaml.MapSlice)
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
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))
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 {
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 {
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)
80 stringArray = append(stringArray, v)
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 {
91 missingKeys = append(missingKeys, k)
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)
105 // does the key match an allowed key?
106 for _, allowedKey := range allowedKeys {
107 if key == allowedKey {
113 // does the key match an allowed pattern?
114 for _, allowedPattern := range allowedPatterns {
115 if allowedPattern.MatchString(key) {
121 invalidKeys = append(invalidKeys, key)
129 // DescribeMap describes a map (for debugging purposes).
130 func DescribeMap(in interface{}, indent string) string {
132 m, ok := in.(map[string]interface{})
134 keys := make([]string, 0)
136 keys = append(keys, k)
139 for _, k := range keys {
141 description += fmt.Sprintf("%s%s:\n", indent, k)
142 description += DescribeMap(v, indent+" ")
146 a, ok := in.([]interface{})
148 for i, v := range a {
149 description += fmt.Sprintf("%s%d:\n", indent, i)
150 description += DescribeMap(v, indent+" ")
154 description += fmt.Sprintf("%s%+v\n", indent, in)
158 // PluralProperties returns the string "properties" pluralized.
159 func PluralProperties(count int) string {
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 {
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) {
186 // StringValue returns the string value of an item.
187 func StringValue(item interface{}) (value string, ok bool) {
188 value, ok = item.(string)
192 intValue, ok := item.(int)
194 return strconv.Itoa(intValue), true