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)