...

Source file src/k8s.io/kubectl/pkg/explain/field_lookup.go

Documentation: k8s.io/kubectl/pkg/explain

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package explain
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"k8s.io/kube-openapi/pkg/util/proto"
    23  )
    24  
    25  // fieldLookup walks through a schema by following a path, and returns
    26  // the final schema.
    27  type fieldLookup struct {
    28  	// Path to walk
    29  	Path []string
    30  
    31  	// Return information: Schema found, or error.
    32  	Schema proto.Schema
    33  	Error  error
    34  }
    35  
    36  // SaveLeafSchema is used to detect if we are done walking the path, and
    37  // saves the schema as a match.
    38  func (f *fieldLookup) SaveLeafSchema(schema proto.Schema) bool {
    39  	if len(f.Path) != 0 {
    40  		return false
    41  	}
    42  
    43  	f.Schema = schema
    44  
    45  	return true
    46  }
    47  
    48  // VisitArray is mostly a passthrough.
    49  func (f *fieldLookup) VisitArray(a *proto.Array) {
    50  	if f.SaveLeafSchema(a) {
    51  		return
    52  	}
    53  
    54  	// Passthrough arrays.
    55  	a.SubType.Accept(f)
    56  }
    57  
    58  // VisitMap is mostly a passthrough.
    59  func (f *fieldLookup) VisitMap(m *proto.Map) {
    60  	if f.SaveLeafSchema(m) {
    61  		return
    62  	}
    63  
    64  	// Passthrough maps.
    65  	m.SubType.Accept(f)
    66  }
    67  
    68  // VisitPrimitive stops the operation and returns itself as the found
    69  // schema, even if it had more path to walk.
    70  func (f *fieldLookup) VisitPrimitive(p *proto.Primitive) {
    71  	// Even if Path is not empty (we're not expecting a leaf),
    72  	// return that primitive.
    73  	f.Schema = p
    74  }
    75  
    76  // VisitKind unstacks fields as it finds them.
    77  func (f *fieldLookup) VisitKind(k *proto.Kind) {
    78  	if f.SaveLeafSchema(k) {
    79  		return
    80  	}
    81  
    82  	subSchema, ok := k.Fields[f.Path[0]]
    83  	if !ok {
    84  		f.Error = fmt.Errorf("field %q does not exist", f.Path[0])
    85  		return
    86  	}
    87  
    88  	f.Path = f.Path[1:]
    89  	subSchema.Accept(f)
    90  }
    91  
    92  func (f *fieldLookup) VisitArbitrary(a *proto.Arbitrary) {
    93  	f.Schema = a
    94  }
    95  
    96  // VisitReference is mostly a passthrough.
    97  func (f *fieldLookup) VisitReference(r proto.Reference) {
    98  	if f.SaveLeafSchema(r) {
    99  		return
   100  	}
   101  
   102  	// Passthrough references.
   103  	r.SubSchema().Accept(f)
   104  }
   105  
   106  // LookupSchemaForField looks for the schema of a given path in a base schema.
   107  func LookupSchemaForField(schema proto.Schema, path []string) (proto.Schema, error) {
   108  	f := &fieldLookup{Path: path}
   109  	schema.Accept(f)
   110  	return f.Schema, f.Error
   111  }
   112  

View as plain text