Skip to content
Browse files

[split] scrooge: expose IDL annotations in generated structs

RB_ID=289353
  • Loading branch information...
1 parent 40e4785 commit 3972e1ac0270be6c9983c5056d74401661771210 Eric Conlon committed with CI Feb 19, 2014
View
27 scrooge-core/src/main/scala/com/twitter/scrooge/ThriftStructMetaData.scala
@@ -94,6 +94,29 @@ final class ThriftStructFieldInfo(
val isOptional: Boolean,
val manifest: Manifest[_],
val keyManifest: scala.Option[Manifest[_]],
- val valueManifest: scala.Option[Manifest[_]]
-)
+ val valueManifest: scala.Option[Manifest[_]],
+ val typeAnnotations: Map[String, String],
+ val fieldAnnotations: Map[String, String]
+) {
+ /**
+ * Secondary constructor provided for backwards compatibility:
+ * Older scrooge-generator does not produce annotations.
+ */
+ def this(
+ tfield: TField,
+ isOptional: Boolean,
+ manifest: Manifest[_],
+ keyManifest: scala.Option[Manifest[_]],
+ valueManifest: scala.Option[Manifest[_]]
+ ) =
+ this(
+ tfield,
+ isOptional,
+ manifest,
+ keyManifest,
+ valueManifest,
+ Map.empty[String, String],
+ Map.empty[String, String]
+ )
+}
View
36 scrooge-generator/src/main/resources/scalagen/struct.scala
@@ -43,15 +43,47 @@ object {{StructName}} extends ThriftStructCodec3[{{StructName}}] {
None,
{{/fieldKeyType}}
{{#fieldValueType}}
- Some(implicitly[Manifest[{{fieldValueType}}]])
+ Some(implicitly[Manifest[{{fieldValueType}}]]),
{{/fieldValueType}}
{{^fieldValueType}}
- None
+ None,
{{/fieldValueType}}
+{{#fieldTypeAnnotations}}
+ immutable$Map(
+{{#pairs}}
+ "{{key}}" -> "{{value}}"
+{{/pairs|,}}
+ ),
+{{/fieldTypeAnnotations}}
+{{^fieldTypeAnnotations}}
+ immutable$Map.empty[String, String],
+{{/fieldTypeAnnotations}}
+{{#fieldFieldAnnotations}}
+ immutable$Map(
+{{#pairs}}
+ "{{key}}" -> "{{value}}"
+{{/pairs|,}}
+ )
+{{/fieldFieldAnnotations}}
+{{^fieldFieldAnnotations}}
+ immutable$Map.empty[String, String]
+{{/fieldFieldAnnotations}}
)
{{/fields|,}}
)
+ lazy val structAnnotations: immutable$Map[String, String] =
+{{#structAnnotations}}
+ immutable$Map[String, String](
+{{#pairs}}
+ "{{key}}" -> "{{value}}"
+{{/pairs|,}}
+ )
+{{/structAnnotations}}
+{{^structAnnotations}}
+ immutable$Map.empty[String, String]
+{{/structAnnotations}}
+
/**
* Checks that all required fields are non-null.
*/
View
19 scrooge-generator/src/main/scala/com/twitter/scrooge/backend/StructTemplate.scala
@@ -142,6 +142,8 @@ trait StructTemplate {
case SetType(valueType, _) => Some(genType(valueType))
case _ => None
}),
+ "fieldTypeAnnotations" -> v(StructTemplate.renderPairs(field.typeAnnotations)),
+ "fieldFieldAnnotations" -> v(StructTemplate.renderPairs(field.fieldAnnotations)),
"isImported" -> v(field.fieldType match {
case n: NamedType => n.scopePrefix.isDefined
case _ => false
@@ -281,7 +283,22 @@ trait StructTemplate {
"arity1" -> v((if (arity == 1) fieldDictionaries.take(1) else Nil)),
"arityN" -> v(arity > 1 && arity <= 22),
"withFieldGettersAndSetters" -> v(isStruct || isException),
- "withTrait" -> v(isStruct)
+ "withTrait" -> v(isStruct),
+ "structAnnotations" -> v(StructTemplate.renderPairs(struct.annotations))
)
}
}
+
+object StructTemplate {
+ /**
+ * Renders a map as:
+ * Dictionary("pairs" -> ListValue(Seq(Dictionary("key" -> ..., "value" -> ...)))
+ */
+ def renderPairs(pairs: Map[String, String]): Dictionary = {
+ val pairDicts: Seq[Dictionary] = (pairs.map { kv =>
+ Dictionary("key" -> codify(kv._1), "value" -> codify(kv._2))
+ } toSeq)
+ Dictionary("pairs" -> v(pairDicts))
+ }
+}
+
View
55 scrooge-generator/src/test/scala/com/twitter/scrooge/ThriftStructMetaDataSpec.scala
@@ -3,6 +3,7 @@ package com.twitter.scrooge
import com.twitter.scrooge.testutil.Spec
import org.apache.thrift.protocol.TType
import scala.collection.{Map, Set}
+import scrooge.test.annotations.thriftscala._
import thrift.test._
// This is a cross project test and I feel bad for putting it here
@@ -82,4 +83,58 @@ class ThriftStructMetaDataSpec extends Spec {
fieldInfo.isOptional must be(true)
}
}
+
+ // XtructColl has no annotations:
+
+ "reports no annotations in field infos" in {
+ val info = XtructColl.fieldInfos(0)
+ info.tfield.name must be("a_map")
+ info.typeAnnotations must be(Map.empty[String, String])
+ info.fieldAnnotations must be(Map.empty[String, String])
+ }
+
+ "reports no struct annotations" in {
+ XtructColl.structAnnotations must be(Map.empty[String, String])
+ }
+
+ // AnnoStruct has one annotation in each position:
+
+ "reports single annotations in field infos" in {
+ val info = AnnoStruct.fieldInfos(0)
+ info.tfield.name must be("structField")
+ info.typeAnnotations must be(Map(
+ "structTypeKey" -> "structTypeValue"
+ ))
+ info.fieldAnnotations must be(Map(
+ "structFieldKey" -> "structFieldValue"
+ ))
+ }
+
+ "reports single struct annotations" in {
+ AnnoStruct.structAnnotations must be(Map(
+ "structKey" -> "structValue"
+ ))
+ }
+
+ // MultiAnnoStruct has two annotations in each position:
+
+ "reports multiple annotations in field infos" in {
+ val info = MultiAnnoStruct.fieldInfos(0)
+ info.tfield.name must be("multiStructField")
+ info.typeAnnotations must be(Map(
+ "structTypeKey1" -> "structTypeValue1",
+ "structTypeKey2" -> "structTypeValue2"
+ ))
+ info.fieldAnnotations must be(Map(
+ "structFieldKey1" -> "structFieldValue1",
+ "structFieldKey2" -> "structFieldValue2"
+ ))
+ }
+
+ "reports multiple struct annotations" in {
+ MultiAnnoStruct.structAnnotations must be(Map(
+ "structKey1" -> "structValue1",
+ "structKey2" -> "structValue2"
+ ))
+ }
}
View
27 scrooge-generator/src/test/thrift/standalone/annotations.thrift
@@ -0,0 +1,27 @@
+namespace java scrooge.test.annotations.thriftjava
+#@namespace scala scrooge.test.annotations.thriftscala
+
+# The data types in this file exercise Thrift annotations in all legal positions.
+
+struct AnnoStruct {
+ 1: string (structTypeKey = "structTypeValue") structField (structFieldKey = "structFieldValue")
+} (structKey = "structValue")
+
+# This version of AnnoStruct exercises multiple annotations.
+struct MultiAnnoStruct {
+ 1: string (structTypeKey1 = "structTypeValue1", structTypeKey2 = "structTypeValue2") multiStructField (structFieldKey1 = "structFieldValue1", structFieldKey2 = "structFieldValue2")
+} (structKey1 = "structValue1", structKey2 = "structValue2")
+
+union AnnoUnion {
+ 1: AnnoStruct unionField (unionFieldKey = "unionFieldValue")
+} (unionKey = "unionValue")
+
+exception AnnoException {
+ 1: string (excTypeKey = "excTypeValue") excField (excFieldKey = "excFieldValue")
+}
+
+service AnnoService {
+ AnnoStruct method(
+ 1: string (methodFieldTypeKey = "methodFieldTypeValue") field (methodFieldFieldKey = "methodFieldFieldValue")
+ ) throws (1: AnnoException exc (methodExcKey = "methodExcValue"))
+}

0 comments on commit 3972e1a

Please sign in to comment.
Something went wrong with that request. Please try again.