github.com/vmware/govmomi@v0.43.0/gen/gen_from_vmodl.rb (about) 1 # Copyright (c) 2014-2024 VMware, 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 $:.unshift(File.expand_path(File.dirname(__FILE__))) 16 17 require "vim_wsdl" 18 19 require "test/unit" 20 21 def read(file) 22 File.open(file) 23 end 24 25 class Prop 26 def initialize(vmodl, data) 27 @vmodl = vmodl 28 @data = data 29 end 30 31 def slice? 32 @data["is-array"] 33 end 34 35 def optional? 36 @data["is-optional"] 37 end 38 39 def name 40 @data["name"] 41 end 42 43 def var_field 44 n = name 45 n[0].capitalize + n[1..-1] 46 end 47 48 def var_type_prefix(base=false) 49 if slice? 50 "[]" 51 else 52 if optional? && !base 53 "*" 54 else 55 "" 56 end 57 end 58 end 59 60 def var_type 61 type = @data["wsdl_type"] 62 if @vmodl.managed_hash.has_key?(type) 63 type = "ManagedObjectReference" 64 end 65 66 # Fix up type from vmodl 67 case type 68 when "TypeName", "MethodName" 69 type = "xsd:string" 70 when "ManagedObject" 71 type = "ManagedObjectReference" 72 when "xsd:anyType" 73 type = "AnyType" 74 end 75 76 if type =~ /^xsd:(.*)$/ 77 type = $1 78 case type 79 when "string" 80 when "int" 81 type = "int32" 82 when "boolean" 83 type ="bool" 84 when "long" 85 type ="int64" 86 when "dateTime" 87 type ="time.Time" 88 when "byte" 89 if slice? 90 return "types.ByteSlice" 91 end 92 when "double" 93 type ="float64" 94 when "float" 95 type ="float32" 96 when "short" 97 type ="int16" 98 when "base64Binary" 99 type ="[]byte" 100 else 101 raise "unknown type: %s" % type 102 end 103 else 104 if Peek.base?(type) 105 type = "Base" + type 106 base = true 107 end 108 type = "types." + type 109 end 110 111 var_type_prefix(base) + type 112 end 113 114 def var_tag 115 "json:\"%s\"" % name 116 end 117 118 def dump(io) 119 io.print "%s %s `%s`\n" % [var_field, var_type, var_tag] 120 end 121 end 122 123 class Managed 124 def initialize(vmodl, name, data) 125 @vmodl = vmodl 126 @name = name 127 @data = data 128 end 129 130 def name 131 @name 132 end 133 134 def props 135 @data["props"].map do |p| 136 Prop.new(@vmodl, p) 137 end 138 end 139 140 def dump(io) 141 include_ref_getter = false 142 include_ent_getter = false 143 144 io.print "type %s struct {\n" % name 145 146 case @data["wsdl_base"] 147 when nil, "ManagedObject", "View" 148 include_ref_getter = true 149 io.print "Self types.ManagedObjectReference `json:\"self\"`\n\n" 150 else 151 io.print "%s\n\n" % @data["wsdl_base"] 152 if @data["wsdl_base"] == "ManagedEntity" 153 include_ent_getter = true 154 end 155 end 156 157 seen = {} 158 props.each do |p| 159 next if seen[p.name] 160 p.dump(io) 161 seen[p.name] = true 162 end 163 io.print "}\n\n" 164 165 if include_ref_getter 166 io.print "func (m %s) Reference() types.ManagedObjectReference {\n" % [name] 167 io.print "return m.Self\n" 168 io.print "}\n\n" 169 end 170 171 if include_ent_getter 172 io.print "func (m *%s) Entity() *ManagedEntity {\n" % [name] 173 io.print "return &m.ManagedEntity\n" 174 io.print "}\n\n" 175 end 176 end 177 178 def dump_init(io) 179 io.print "func init() {\n" 180 io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name] 181 io.print "}\n\n" 182 end 183 end 184 185 class Vmodl 186 def initialize(data) 187 @data = Marshal.load(data) 188 end 189 190 def managed_hash 191 @managed_hash ||= begin 192 h = {} 193 managed.each do |m| 194 h[m.name] = m 195 end 196 h 197 end 198 end 199 200 def managed 201 @data.map do |k,v| 202 next if !v.is_a?(Hash) 203 next if v["kind"] != "managed" 204 # rbvmomi/vmodl.db includes pbm mo's, but we don't need the types as they have no properties 205 next if k =~ /^pbm/i 206 # internal/types.go already includes these 207 next if ["InternalDynamicTypeManager", "ReflectManagedMethodExecuter"].include?(k) 208 Managed.new(self, k, v) 209 end.compact 210 end 211 end 212 213 if !File.directory?(ARGV.first) 214 raise "first argument not a directory" 215 end 216 217 wsdl = WSDL.new(WSDL.read(ARGV[1]+".wsdl"), nil) 218 wsdl.validate_assumptions! 219 wsdl.peek() 220 221 vmodl = Vmodl.new(read ARGV[2] || "./rbvmomi/vmodl.db") 222 223 File.open(File.join(ARGV.first, "mo/mo.go"), "w") do |io| 224 io.print WSDL.header("mo") 225 io.print <<EOF 226 import ( 227 "github.com/vmware/govmomi/vim25/types" 228 ) 229 EOF 230 231 vmodl. 232 managed. 233 sort_by { |m| m.name }. 234 each { |m| m.dump(io); m.dump_init(io); } 235 end 236 237 exit(0)