summaryrefslogtreecommitdiff
path: root/swift/src/Ice/ClassResolver.swift
blob: 0f6903f464eff091bb17816294c1d75e0178cb37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//

import Foundation

open class ValueTypeResolver: NSObject {
    open func type() -> Value.Type {
        fatalError("Abstract method")
    }
}

open class UserExceptionTypeResolver: NSObject {
    open func type() -> UserException.Type {
        fatalError("Abstract method")
    }
}

//
// The generated code for Slice classes and exceptions provides an extension for
// Ice.ClassResolver with a static function that returns a ValueTypeResolver or
// UserExceptionTypeResolver.
//
public class ClassResolver: NSObject {
    private static func resolveImpl(typeId: String, prefix: String?) -> AnyObject? {
        return autoreleasepool {
            let start = typeId.index(typeId.startIndex, offsetBy: 2)
            let selector = Selector((prefix ?? "") + typeId[start...].replacingOccurrences(of: "::", with: "_"))
            guard ClassResolver.responds(to: selector) else {
                return nil
            }
            return ClassResolver.perform(selector).takeUnretainedValue()
        }
    }

    static func resolve(typeId: String, prefix: String? = nil) -> Value.Type? {
        guard let t = resolveImpl(typeId: typeId, prefix: prefix) as? ValueTypeResolver else {
            return nil
        }
        return t.type()
    }

    static func resolve(typeId: String, prefix: String? = nil) -> UserException.Type? {
        guard let t = resolveImpl(typeId: typeId, prefix: prefix) as? UserExceptionTypeResolver else {
            return nil
        }
        return t.type()
    }
}

public class TypeIdResolver: NSObject {
    static func resolve(compactId: Int32) -> String? {
        return autoreleasepool {
            let selector = Selector("TypeId_\(compactId)")

            guard TypeIdResolver.responds(to: selector) else {
                return nil
            }

            let val = TypeIdResolver.perform(selector).takeUnretainedValue()

            guard let typeId = val as? String else {
                preconditionFailure("unexpected value type")
            }
            return typeId
        }
    }
}