ads_common/lib/ads_common/parameters_validator.rb
def validate_choice_argument(item, parent, key, item_type)
      result = false
      if item_type.kind_of?(Hash) && item_type.include?(:choices)
        # If we have an array of choices, we need to go over them individually.
        # We drop original array and replace it with the generated one that's
        # nested one level more.
        if item.kind_of?(Array)
          parent[key] = []
          item.each do |sub_item|
            unless validate_choice_argument(sub_item, parent, key, item_type)
              validate_arg(sub_item, parent, key, item_type)
            end
          end
          return true
        end
        # New root needed for extra nesting we have (choice field).
        new_root = {}
        choice_items = arrayize(item)
        choice_items.each do |choice_item|
          choice_type = choice_item.delete(:xsi_type)
          choice_item_type =
              find_choice_by_xsi_type(choice_type, item_type[:choices])
          if choice_type.nil? || choice_item_type.nil?
            raise AdsCommon::Errors::TypeMismatchError.new(
              'choice subtype', choice_type, choice_item.to_s())
          end
          choice_item[:xsi_type] = choice_type
          # Note we use original name that produces a string like
          # "BasicUserList". That's needed as the name is generated out of
          # standard naming ("basicUserList") which would otherwise be produced.
          choice_key = choice_item_type[:original_name]
          new_root[choice_key] = choice_item
          type_signature = get_full_type_signature(choice_type)
          validate_arg(choice_item, new_root, choice_key, type_signature)
        end
        if parent[key].kind_of?(Array)
          parent[key] << new_root
        else
          parent[key] = new_root
        end
        result = true
      end
      return result
    end
def validate_choice_argument(item, parent, key, item_type)
      result = false
      if item_type.kind_of?(Hash) && item_type.include?(:choices)
        # If we have an array of choices, we need to go over them individually.
        # We drop original array and replace it with the generated one that's
        # nested one level more.
        if item.kind_of?(Array)
          parent[key] = []
          item.each do |sub_item|
            unless validate_choice_argument(sub_item, parent, key, item_type)
              validate_arg(sub_item, parent, key, item_type)
            end
          end
          return true
        end
        # New root needed for extra nesting we have (choice field).
        new_root = {}
        choice_items = arrayize(item)
        choice_items.each do |choice_item|
          choice_type = choice_item.delete(:xsi_type)
          choice_item_type =
              find_choice_by_xsi_type(choice_type, item_type[:choices])
          if choice_type.nil? || choice_item_type.nil?
            raise AdsCommon::Errors::TypeMismatchError.new(
              'choice subtype', choice_type, choice_item.to_s())
          end
          choice_item[:xsi_type] = choice_type
          # Note we use original name that produces a string like
          # "BasicUserList". That's needed as the name is generated out of
          # standard naming ("basicUserList") which would otherwise be produced.
          choice_key = choice_item_type[:original_name]
          new_root[choice_key] = choice_item
          type_signature = get_full_type_signature(choice_type)
          validate_arg(choice_item, new_root, choice_key, type_signature)
        end
        if parent[key].kind_of?(Array)
          parent[key] << new_root
        else
          parent[key] = new_root
        end
        result = true
      end
      return result
    end
Special handling for choice types. Goes over each item, checks xsi_type
 is set and correct and injects new node for it into the tree. After that,
 recurces with the correct item type.