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