in scrooge-generator/src/main/scala/com/twitter/scrooge/backend/StructTemplate.scala [633:745]
private def basename(fqdn: String): String = fqdn.split('.').last
def structDict(
struct: StructLike,
namespace: Option[Identifier],
includes: Seq[Include],
serviceOptions: Set[ServiceOption],
genAdapt: Boolean,
toplevel: Boolean =
false, // True if this struct is defined in its own file. False for internal structs.
// Set a default value for now to not break API for other AST,
// the default ThriftValidator will be used if set to `None`.
validator: Option[Identifier] = None
): Dictionary = {
val fullyQualifiedThriftExn = "_root_.com.twitter.scrooge.ThriftException"
val fullyQualifiedSourcedExn = "_root_.com.twitter.finagle.SourcedException"
val parentType = struct match {
case e: Exception_ if serviceOptions.contains(WithFinagle) =>
s"$fullyQualifiedThriftExn with $fullyQualifiedSourcedExn with ThriftStruct"
case e: Exception_ => s"$fullyQualifiedThriftExn with ThriftStruct"
case u: Union => "ThriftUnion"
case result: FunctionResult =>
val resultType = getSuccessType(result)
s"ThriftResponse[$resultType] with ThriftStruct"
case _ => "ThriftStruct"
}
val arity = struct.fields.size
val isStruct = struct.isInstanceOf[Struct]
val isException = struct.isInstanceOf[Exception_]
val isUnion = struct.isInstanceOf[Union]
val isResponse = struct.isInstanceOf[FunctionResult]
val hasValidator = validator.isDefined
val exceptionMsgField: Option[SimpleID] =
if (isException) exceptionMsgFieldName(struct) else None
val nonOptionalFields = struct.fields.filter(field =>
field.requiredness.isRequired || field.requiredness.isDefault || Generator
.isConstructionRequiredField(field))
val nonOptionalFieldDictionaries = fieldsToDict(
nonOptionalFields,
if (isException) Seq("message") else Nil,
namespace
)
val fieldDictionaries = fieldsToDict(
struct.fields,
if (isException) Seq("message") else Nil,
namespace
)
val firstFieldName =
if (struct.fields.nonEmpty) genID(struct.fields.head.sid.toTitleCase) else v("")
val firstFieldValue =
if (struct.fields.nonEmpty) genUnsafeEmptyReadValue(struct.fields.head) else v("null")
val structName = if (toplevel) genID(struct.sid.toTitleCase) else genID(struct.sid)
val pkg = namespace.map(genID).getOrElse(v(""))
val pkgName = v(basename(pkg.toData))
val thriftValidator = validator match {
case Some(vd) => v("Some(new " + vd.fullName + "())")
case _ => v("scala.None")
}
Dictionary(
"public" -> v(toplevel),
"package" -> pkg,
"packageName" -> pkgName,
"docstring" -> v(struct.docstring.getOrElse("")),
"parentType" -> v(parentType),
"firstFieldName" -> firstFieldName,
"firstFieldValue" -> firstFieldValue,
"fields" -> v(fieldDictionaries),
"hasFields" -> v(fieldDictionaries.nonEmpty),
"nonOptionalFields" -> v(nonOptionalFieldDictionaries),
"defaultFields" -> v(fieldsToDict(struct.fields.filter(!_.requiredness.isOptional), Nil)),
"alternativeConstructor" -> v(
struct.fields.exists(_.requiredness.isOptional)
&& struct.fields.exists(_.requiredness.isDefault)
),
"generateStructProxy" -> v(
struct.annotations
.getOrElse("com.twitter.scrooge.scala.generateStructProxy", "false") == "true"),
"hasConstructionRequiredFields" -> v(
struct.fields.exists(Generator.isConstructionRequiredField)
),
"hasNonOptionalFields" -> v(nonOptionalFields.nonEmpty),
"StructNameForWire" -> v(struct.originalName),
"StructName" ->
structName,
"InstanceClassName" -> (if (isStruct) v("Immutable") else structName),
"underlyingStructName" -> genID(struct.sid.prepend("_underlying_")),
"arity" -> v(arity.toString),
"isUnion" -> v(isUnion),
"isException" -> v(isException),
"isResponse" -> v(isResponse),
"hasExceptionMessage" -> v(exceptionMsgField.isDefined),
"exceptionMessageField" -> exceptionMsgField.map(genID).getOrElse { v("") },
"product" -> v(productN(struct.fields, namespace)),
"tuple" -> v(tupleN(struct.fields, namespace)),
"arity0" -> v(arity == 0),
"arity1" -> v(if (arity == 1) fieldDictionaries.take(1) else Nil),
"arityN" -> v(arity > 1 && arity <= 22),
"arity1ThroughN" -> v(arity >= 1 && arity <= 22),
"withFieldGettersAndSetters" -> v(isStruct || isException),
"withTrait" -> v(isStruct),
"adapt" -> v(genAdapt),
"hasFailureFlags" -> v(isException && serviceOptions.contains(WithFinagle)),
"structAnnotations" -> TemplateGenerator.renderPairs(struct.annotations),
"validator" -> thriftValidator
)
}