github.com/vmware/govmomi@v0.37.2/gen/gen_from_vmodl.rb (about)

     1  # Copyright (c) 2014 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        when "double"
    90          type ="float64"
    91        when "float"
    92          type ="float32"
    93        when "short"
    94          type ="int16"
    95        when "base64Binary"
    96          type ="[]byte"
    97        else
    98          raise "unknown type: %s" % type
    99        end
   100      else
   101        if Peek.base?(type)
   102          type = "Base" + type
   103          base = true
   104        end
   105        type = "types." + type
   106      end
   107  
   108      var_type_prefix(base) + type
   109    end
   110  
   111    def var_tag
   112      "json:\"%s\"" % name
   113    end
   114  
   115    def dump(io)
   116      io.print "%s %s `%s`\n" % [var_field, var_type, var_tag]
   117    end
   118  end
   119  
   120  class Managed
   121    def initialize(vmodl, name, data)
   122      @vmodl = vmodl
   123      @name = name
   124      @data = data
   125    end
   126  
   127    def name
   128      @name
   129    end
   130  
   131    def props
   132      @data["props"].map do |p|
   133        Prop.new(@vmodl, p)
   134      end
   135    end
   136  
   137    def dump(io)
   138      include_ref_getter = false
   139      include_ent_getter = false
   140  
   141      io.print "type %s struct {\n" % name
   142  
   143      case @data["wsdl_base"]
   144      when nil, "ManagedObject", "View"
   145        include_ref_getter = true
   146        io.print "Self types.ManagedObjectReference `json:\"self\"`\n\n"
   147      else
   148        io.print "%s\n\n" % @data["wsdl_base"]
   149        if @data["wsdl_base"] == "ManagedEntity"
   150          include_ent_getter = true
   151        end
   152      end
   153  
   154      seen = {}
   155      props.each do |p|
   156        next if seen[p.name]
   157        p.dump(io)
   158        seen[p.name] = true
   159      end
   160      io.print "}\n\n"
   161  
   162      if include_ref_getter
   163        io.print "func (m %s) Reference() types.ManagedObjectReference {\n" % [name]
   164        io.print "return m.Self\n"
   165        io.print "}\n\n"
   166      end
   167  
   168      if include_ent_getter
   169        io.print "func (m *%s) Entity() *ManagedEntity {\n" % [name]
   170        io.print "return &m.ManagedEntity\n"
   171        io.print "}\n\n"
   172      end
   173    end
   174  
   175    def dump_init(io)
   176      io.print "func init() {\n"
   177      io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
   178      io.print "}\n\n"
   179    end
   180  end
   181  
   182  class Vmodl
   183    def initialize(data)
   184      @data = Marshal.load(data)
   185    end
   186  
   187    def managed_hash
   188      @managed_hash ||= begin
   189                          h = {}
   190                          managed.each do |m|
   191                            h[m.name] = m
   192                          end
   193                          h
   194                        end
   195    end
   196  
   197    def managed
   198      @data.map do |k,v|
   199        next if !v.is_a?(Hash)
   200        next if v["kind"] != "managed"
   201        # rbvmomi/vmodl.db includes pbm mo's, but we don't need the types as they have no properties
   202        next if k =~ /^pbm/i
   203        # internal/types.go already includes these
   204        next if ["InternalDynamicTypeManager", "ReflectManagedMethodExecuter"].include?(k)
   205        Managed.new(self, k, v)
   206      end.compact
   207    end
   208  end
   209  
   210  if !File.directory?(ARGV.first)
   211    raise "first argument not a directory"
   212  end
   213  
   214  wsdl = WSDL.new(WSDL.read(ARGV[1]+".wsdl"), nil)
   215  wsdl.validate_assumptions!
   216  wsdl.peek()
   217  
   218  vmodl = Vmodl.new(read ARGV[2] || "./rbvmomi/vmodl.db")
   219  
   220  File.open(File.join(ARGV.first, "mo/mo.go"), "w") do |io|
   221    io.print WSDL.header("mo")
   222    io.print <<EOF
   223  import (
   224          "github.com/vmware/govmomi/vim25/types"
   225  )
   226  EOF
   227  
   228    vmodl.
   229      managed.
   230      sort_by { |m| m.name }.
   231      each { |m| m.dump(io); m.dump_init(io); }
   232  end
   233  
   234  exit(0)