Permalink
Browse files

Merge branch 'tmp'

  • Loading branch information...
2 parents 327b67a + a501862 commit e0121119b4a9b2cda85b69c71a9d0a2a104e9b18 Jenkins (CI) committed Feb 28, 2014
View
@@ -6,7 +6,7 @@ import com.typesafe.sbt.site.SphinxSupport.Sphinx
object Scrooge extends Build {
val libVersion = "3.12.3"
val utilVersion = "6.12.1"
- val finagleVersion = "6.12.1"
+ val finagleVersion = "6.12.2"
def util(which: String) = "com.twitter" %% ("util-"+which) % utilVersion
def finagle(which: String) = "com.twitter" %% ("finagle-"+which) % finagleVersion
@@ -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]
+ )
+}
@@ -101,13 +101,13 @@
<dependency>
<groupId>com.twitter</groupId>
<artifactId>finagle-core</artifactId>
- <version>6.12.2-SNAPSHOT</version>
+ <version>6.12.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.twitter</groupId>
<artifactId>finagle-thrift</artifactId>
- <version>6.12.2-SNAPSHOT</version>
+ <version>6.12.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -10,5 +10,13 @@ _field.`type` match {
{{gotName}} = true
{{/required}}
}
- case _ => // skip
+ case _actualType =>
+ val _expectedType = TType.{{#isEnum}}ENUM{{/isEnum}}{{^isEnum}}{{constType}}{{/isEnum}}
+
+ throw new TProtocolException(
+ "Received wrong type for field '{{fieldName}}' (expected=%s, actual=%s).".format(
+ ttypeToHuman(_expectedType),
+ ttypeToHuman(_actualType)
+ )
+ )
}
@@ -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.
*/
@@ -166,6 +198,28 @@ object {{StructName}} extends ThriftStructCodec3[{{StructName}}] {
{{/fields}}
+
+ private def ttypeToHuman(byte: Byte) = {
+ // from https://github.com/apache/thrift/blob/master/lib/java/src/org/apache/thrift/protocol/TType.java
+ byte match {
+ case TType.STOP => "STOP"
+ case TType.VOID => "VOID"
+ case TType.BOOL => "BOOL"
+ case TType.BYTE => "BYTE"
+ case TType.DOUBLE => "DOUBLE"
+ case TType.I16 => "I16"
+ case TType.I32 => "I32"
+ case TType.I64 => "I64"
+ case TType.STRING => "STRING"
+ case TType.STRUCT => "STRUCT"
+ case TType.MAP => "MAP"
+ case TType.SET => "SET"
+ case TType.LIST => "LIST"
+ case TType.ENUM => "ENUM"
+ case _ => "UNKNOWN"
+ }
+ }
+
{{#withTrait}}
object Immutable extends ThriftStructCodec3[{{StructName}}] {
override def encode(_item: {{StructName}}, _oproto: TProtocol) { _item.write(_oproto) }
@@ -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))
+ }
+}
+
@@ -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"
+ ))
+ }
}
@@ -476,6 +476,27 @@ class ScalaGeneratorSpec extends JMockSpec with EvalHelper {
}
}
}
+
+ "wrong type" should {
+ val protocol = new TBinaryProtocol(new TMemoryBuffer(10000))
+
+ protocol.writeStructBegin(new TStruct("test"))
+ protocol.writeFieldBegin(new TField("number", TType.I32, 1))
+ protocol.writeI32(4000)
+ protocol.writeFieldEnd()
+ protocol.writeFieldStop()
+ protocol.writeStructEnd()
+
+ "throw an exception" in { _ =>
+ val ex = intercept[TProtocolException] {
+ RequiredString.decode(protocol)
+ }
+
+ ex.toString.contains("value") must be(true)
+ ex.toString.contains("actual=I32") must be(true)
+ ex.toString.contains("expected=STRING") must be(true)
+ }
+ }
}
"with optional fields" should {
@@ -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"))
+}
View
@@ -20,12 +20,12 @@
<dependency>
<groupId>com.twitter</groupId>
<artifactId>finagle-thrift</artifactId>
- <version>6.12.2-SNAPSHOT</version>
+ <version>6.12.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.twitter</groupId>
<artifactId>finagle-ostrich4</artifactId>
- <version>6.12.2-SNAPSHOT</version>
+ <version>6.12.3-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
View
@@ -25,7 +25,7 @@
<dependency>
<groupId>com.twitter</groupId>
<artifactId>finagle-thrift</artifactId>
- <version>6.12.2-SNAPSHOT</version>
+ <version>6.12.3-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

0 comments on commit e012111

Please sign in to comment.