All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.smithy.kotlin.codegen.model.SymbolExt.kt Maven / Gradle / Ivy

/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

package software.amazon.smithy.kotlin.codegen.model

import software.amazon.smithy.codegen.core.Symbol
import software.amazon.smithy.codegen.core.SymbolReference
import software.amazon.smithy.kotlin.codegen.core.KotlinDependency
import software.amazon.smithy.kotlin.codegen.utils.getOrNull
import software.amazon.smithy.model.shapes.Shape

/**
 * Property bag keys used by symbol provider implementation
 */
object SymbolProperty {
    // The key that holds the default value for a type (symbol) as a string
    const val DEFAULT_VALUE_KEY: String = "defaultValue"

    // Boolean property indicating this symbol should be boxed
    const val BOXED_KEY: String = "boxed"

    // the original shape the symbol was created from
    const val SHAPE_KEY: String = "shape"

    // Mutable collection type
    const val MUTABLE_COLLECTION_FUNCTION: String = "mutableCollectionType"

    // Immutable collection type
    const val IMMUTABLE_COLLECTION_FUNCTION: String = "immutableCollectionType"

    // Entry type for Maps
    const val ENTRY_EXPRESSION: String = "entryExpression"
}

/**
 * Test if a symbol is boxed
 */
val Symbol.isBoxed: Boolean
    get() = getProperty(SymbolProperty.BOXED_KEY).map {
        when (it) {
            is Boolean -> it
            else -> false
        }
    }.orElse(false)

/**
 * Test if a symbol is not boxed
 */
val Symbol.isNotBoxed: Boolean
    get() = !isBoxed

/**
 * Gets the default value for the symbol if present, else null
 * @param defaultBoxed the string to pass back for boxed values
 */
fun Symbol.defaultValue(defaultBoxed: String? = "null"): String? {
    // boxed types should always be defaulted to null
    if (isBoxed) {
        return defaultBoxed
    }

    val default = getProperty(SymbolProperty.DEFAULT_VALUE_KEY, String::class.java)
    return if (default.isPresent) default.get() else null
}

/**
 * Mark a symbol as being boxed (nullable) i.e. `T?`
 */
fun Symbol.Builder.boxed(): Symbol.Builder = apply { putProperty(SymbolProperty.BOXED_KEY, true) }

/**
 * Set the default value used when formatting the symbol
 */
fun Symbol.Builder.defaultValue(value: String): Symbol.Builder = apply { putProperty(SymbolProperty.DEFAULT_VALUE_KEY, value) }

/**
 * Convenience function for specifying kotlin namespace
 */
fun Symbol.Builder.namespace(name: String): Symbol.Builder = namespace(name, ".")

/**
 * Convenience function for specifying a symbol is a subnamespace of the [dependency].
 *
 * This will implicitly add the dependecy to the builder since it is known that it comes from the
 * dependency namespace.
 *
 * Equivalent to:
 * ```
 * builder.addDependency(dependency)
 * builder.namespace("${dependency.namespace}.subnamespace")
 * ```
 */
fun Symbol.Builder.namespace(dependency: KotlinDependency, subnamespace: String = ""): Symbol.Builder {
    addDependency(dependency)
    return if (subnamespace.isEmpty()) {
        namespace(dependency.namespace)
    } else {
        namespace("${dependency.namespace}.${subnamespace.trimStart('.')}")
    }
}

/**
 * Add a reference to a symbol coming from a kotlin dependency
 */
fun Symbol.Builder.addReference(dependency: KotlinDependency, name: String, subnamespace: String = ""): Symbol.Builder {
    val refSymbol = Symbol.builder()
        .name(name)
        .namespace(dependency, subnamespace)
        .build()
    return addReference(refSymbol)
}

/**
 * Add a reference to the given symbol with the context option
 */
fun Symbol.Builder.addReference(symbol: Symbol, option: SymbolReference.ContextOption): Symbol.Builder {
    val ref = SymbolReference.builder()
        .symbol(symbol)
        .options(option)
        .build()

    return addReference(ref)
}

/**
 * Get the shape this symbol was created from
 */
val Symbol.shape: Shape?
    get() = getProperty(SymbolProperty.SHAPE_KEY, Shape::class.java).getOrNull()




© 2015 - 2025 Weber Informatics LLC | Privacy Policy