override fun validate()

in thrifty-schema/src/main/kotlin/com/microsoft/thrifty/schema/Constant.kt [245:316]


        override fun validate(symbolTable: SymbolTable, expected: ThriftType, valueElement: ConstValueElement) {
            if (expected !is EnumType) {
                throw IllegalStateException("bad enum literal")
            }

            when (valueElement) {
                is IntValueElement -> {
                    val id = valueElement.value
                    if (expected.members.any { it.value.toLong() == id }) {
                        return
                    }
                    throw IllegalStateException("'$id' is not a valid value for ${expected.name}")
                }

                is IdentifierValueElement -> {
                    // An IDENTIFIER enum value could be one of four kinds of entities:
                    // 1. Another constant, possibly of the correct type
                    // 2. A fully-qualified imported enum value, e.g. file.Enum.Member
                    // 3. An imported, partially-qualified enum value, e.g. Enum.Member (where Enum is imported)
                    // 4. A fully-qualified, non-imported enum value, e.g. Enum.Member
                    //
                    // Apache accepts all of these, and so do we.
                    val id = valueElement.value

                    // An unusual edge case is when a named constant has the same name as an enum
                    // member; in this case, constants take precedence over members.  Make sure that
                    // the type is as expected!
                    val constant = symbolTable.lookupConst(id)
                    if (constant != null && constant.type.trueType == expected) {
                        return
                    }

                    var ix = id.lastIndexOf('.')
                    if (ix == -1) {
                        throw IllegalStateException(
                                "Unqualified name '$id' is not a valid enum constant value: (${valueElement.location})")
                    }

                    val typeName = id.substring(0, ix) // possibly qualified
                    val memberName = id.substring(ix + 1)

                    // Does the literal name match the expected type name?
                    // It could be that typeName is qualified; handle that case.
                    var typeNameMatches = false
                    ix = typeName.indexOf('.')
                    if (ix == -1) {
                        // unqualified
                        if (expected.name == typeName) {
                            typeNameMatches = true
                        }
                    } else {
                        // qualified
                        val qualifier = typeName.substring(0, ix)
                        val actualName = typeName.substring(ix + 1)

                        // Does the qualifier match?
                        if (expected.location.programName == qualifier && expected.name == actualName) {
                            typeNameMatches = true
                        }
                    }

                    if (typeNameMatches && expected.members.any { it.name == memberName }) {
                        return
                    }

                    throw IllegalStateException(
                            "'$id' is not a member of enum type ${expected.name}: members=${expected.members}")
                }

                else -> throw IllegalStateException("bad enum literal: $valueElement")
            }
        }