// SPDX-FileCopyrightText: Copyright The Lima Authors1// SPDX-License-Identifier: Apache-2.023// This file has been adapted from https://github.com/containerd/nerdctl/blob/v1.0.0/pkg/reflectutil/reflectutil.go4/*5Copyright The containerd Authors.6Licensed under the Apache License, Version 2.0 (the "License");7you may not use this file except in compliance with the License.8You may obtain a copy of the License at9http://www.apache.org/licenses/LICENSE-2.010Unless required by applicable law or agreed to in writing, software11distributed under the License is distributed on an "AS IS" BASIS,12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13See the License for the specific language governing permissions and14limitations under the License.15*/1617package reflectutil1819import (20"fmt"21"reflect"22)2324func UnknownNonEmptyFields(structOrStructPtr any, knownNames ...string) []string {25var unknown []string26knownNamesMap := make(map[string]struct{}, len(knownNames))27for _, name := range knownNames {28knownNamesMap[name] = struct{}{}29}30origVal := reflect.ValueOf(structOrStructPtr)31var val reflect.Value32switch kind := origVal.Kind(); kind {33case reflect.Ptr:34val = origVal.Elem()35case reflect.Struct:36val = origVal37default:38panic(fmt.Errorf("expected Ptr or Struct, got %+v", kind))39}40for i := range val.NumField() {41iField := val.Field(i)42if isEmpty(iField) {43continue44}45iName := val.Type().Field(i).Name46if _, ok := knownNamesMap[iName]; !ok {47unknown = append(unknown, iName)48}49}50return unknown51}5253func isEmpty(v reflect.Value) bool {54// NOTE: IsZero returns false for zero-length map and slice55if v.IsZero() {56return true57}58switch v.Kind() {59case reflect.Map, reflect.Slice:60return v.Len() == 061}62return false63}646566