You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Talked offline, here's a dump of reflective extensions we currently employ because 🙃
packagecom.uber.thriftyextensionsimportcom.microsoft.thrifty.schema.Fieldimportcom.microsoft.thrifty.schema.Locationimportcom.microsoft.thrifty.schema.Requirednessimportcom.microsoft.thrifty.schema.UserElementimportcom.microsoft.thrifty.schema.UserTypeimportcom.microsoft.thrifty.schema.parser.ConstValueElementimportcom.microsoft.thrifty.schema.parser.FieldElementimportjava.lang.reflect.Modifierimportjava.util.UUID/* * Unsafe reflection-based extensions to Thrifty's APIs. Necessary because there's no APIs available * for adjusting [FieldElement] APIs.*//** * Creates a new copy of this [Field] with `required` [Field.required]ness reflectively set via its * internal [FieldElement] field. * * @receiver the source [Field] to use. A defensive copy will be made. * @return the new [Field] instance.*/fun Field.makeRequired(): Field {
val newElement = (elementField.get(this) asFieldElement).copy(requiredness =Requiredness.REQUIRED)
return toBuilder().build()
.apply {
elementField.set(this, newElement)
}
}
/** * Creates a new copy of this [Field] with `optional` [Field.required]ness reflectively set via its * internal [FieldElement] field. * * @receiver the source [Field] to use. A defensive copy will be made. * @return the new [Field] instance.*/fun Field.makeOptional(): Field {
val newElement = (elementField.get(this) asFieldElement).copy(requiredness =Requiredness.OPTIONAL)
return toBuilder().build()
.apply {
elementField.set(this, newElement)
}
}
/** * Creates a new copy of this [Field] with the specified [value] default value reflectively set via * its internal [FieldElement] field. * * @receiver the source [Field] to use. A defensive copy will be made. * @return the new [Field] instance.*/fun Field.withDefaultValue(value:ConstValueElement): Field {
val newElement = (elementField.get(this) asFieldElement).copy(constValue = value)
return toBuilder().build()
.apply {
elementField.set(this, newElement)
}
}
/** * Creates a new copy of this [Field] with the specified [newId] reflectively set via its internal * [FieldElement] field. * * @param newId the new id to set. * @receiver the source [Field] to use. A defensive copy will be made. * @return the new [Field] instance.*/fun Field.newId(newId:Int): Field {
val newElement = (elementField.get(this) asFieldElement).copy(fieldId = newId)
return toBuilder().build()
.apply {
elementField.set(this, newElement)
}
}
/** * Ensures [this] list of [Field]s are valid (such as ensuring they've got unique field IDs). * * @param ensuredLocation the [Location] of the element holding this list to ensure fields match it. * @receiver the source list to check. A defensive new copy will be made. * @return the new fields list with the new field appended to the end.*/fun List<Field>.asSafeFields(ensuredLocation:Location): List<Field> {
if (distinctBy { it.id }.size == size) {
// They're all distinct, just return them with locations ensuredreturn map {
it.toBuilder()
.location(it.location.matchTo(ensuredLocation))
.build()
}
}
val safeFields = fold(emptyList<Field>()) { cur, next ->
cur.safeAddField(next, ensuredLocation)
}
check(safeFields.size == size) {
"Data lost!"
}
return safeFields
}
/** * Safely adds a new [Field] to this collection while ensuring that it does not conflict with the * existing field ids. * * @param newField the new [Field] to add. * @param ensuredLocation the [Location] of the element holding this list to ensure fields match it. * @receiver the source list to add this to. A defensive new copy will be made. * @return the new fields list with the new field appended to the end.*/fun List<Field>.safeAddField(newField:Field, ensuredLocation:Location): List<Field> {
val defensiveCopy = newField.toBuilder()
.location(newField.location.matchTo(ensuredLocation))
.build()
if (none { it.id == newField.id }) {
return plus(defensiveCopy)
}
val finalField = map(Field::id).max()?.let { maxId ->
defensiveCopy.newId(maxId +1)
} ?: defensiveCopy
return plus(finalField)
}
privatefun Location.matchTo(source:Location): Location {
returnif (base == source.base && path == source.path) {
this
} else {
Location.get(source.base, source.path)
}
}
/** * Creates a new copy of this [Field] with the specified [newUUID] reflectively set via its internal * [FieldElement] field. * * @param newUUID the new UUID to use. Defaults to a randomly generated one. * @receiver the source [Field] to use. A defensive copy will be made. * @return the new [Field] instance.*/fun <T:UserElement> T.newUuid(newUUID:UUID = UUID.randomUUID()): T {
if (thisisUserType) {
UserType::class.java.getDeclaredField("mixin")
} else {
javaClass.getDeclaredField("mixin")
}
.apply {
isAccessible =trueval modifiersField = java.lang.reflect.Field::class.java
.getDeclaredField("modifiers")
modifiersField.isAccessible =true
modifiersField.setInt(this, modifiers andModifier.FINAL.inv())
}
.get(this)
.let { mixin ->// UserElementMixin
mixin.javaClass.getDeclaredField("uuid")
.apply {
isAccessible =trueval modifiersField = java.lang.reflect.Field::class.java
.getDeclaredField("modifiers")
modifiersField.isAccessible =true
modifiersField.setInt(this, modifiers andModifier.FINAL.inv())
}
.apply {
val olduuid = uuid
set(mixin, newUUID)
check(olduuid != uuid) {
"New UUID setting failed!"
}
}
}
returnthis
}
/** * Sets a new default value for a given [Field]. * * @param const the new [ConstValueElement] to set * @return this same [Field] instance.*/fun Field.setDefaultValue(const:ConstValueElement): Field {
val newElement = (elementField.get(this) asFieldElement).copy(constValue = const)
elementField.set(this, newElement)
returnthis
}
privateval elementField =Field::class.java.getDeclaredField("element")
.apply {
isAccessible =trueval modifiersField = java.lang.reflect.Field::class.java
.getDeclaredField("modifiers")
modifiersField.isAccessible =true
modifiersField.setInt(this, modifiers andModifier.FINAL.inv())
}
The text was updated successfully, but these errors were encountered:
Talked offline, here's a dump of reflective extensions we currently employ because 🙃
The text was updated successfully, but these errors were encountered: