Skip to content

Instantly share code, notes, and snippets.

@cb372
Created August 26, 2015 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cb372/2d19d5f84af39f4edcd5 to your computer and use it in GitHub Desktop.
Save cb372/2d19d5f84af39f4edcd5 to your computer and use it in GitHub Desktop.
Example Thrift model and Scrooge-generated code
/**
* Generated by Scrooge
* version: 3.16.3
* rev: b8593c83072d94fc44feaa8d97940b9266d84ed0
* built at: 20140806-054445
*/
package com.mycorp
import com.twitter.scrooge.{
TFieldBlob, ThriftException, ThriftStruct, ThriftStructCodec3, ThriftStructFieldInfo, ThriftUtil}
import org.apache.thrift.protocol._
import org.apache.thrift.transport.{TMemoryBuffer, TTransport}
import java.nio.ByteBuffer
import java.util.Arrays
import scala.collection.immutable.{Map => immutable$Map}
import scala.collection.mutable.Builder
import scala.collection.mutable.{
ArrayBuffer => mutable$ArrayBuffer, Buffer => mutable$Buffer,
HashMap => mutable$HashMap, HashSet => mutable$HashSet}
import scala.collection.{Map, Set}
object Bar extends ThriftStructCodec3[Bar] {
private val NoPassthroughFields = immutable$Map.empty[Short, TFieldBlob]
val Struct = new TStruct("Bar")
val AField = new TField("a", TType.STRING, 1)
val AFieldManifest = implicitly[Manifest[String]]
val BField = new TField("b", TType.I32, 2)
val BFieldManifest = implicitly[Manifest[Int]]
/**
* Field information in declaration order.
*/
lazy val fieldInfos: scala.List[ThriftStructFieldInfo] = scala.List[ThriftStructFieldInfo](
new ThriftStructFieldInfo(
AField,
false,
AFieldManifest,
None,
None,
immutable$Map(
),
immutable$Map(
)
),
new ThriftStructFieldInfo(
BField,
true,
BFieldManifest,
None,
None,
immutable$Map(
),
immutable$Map(
)
)
)
lazy val structAnnotations: immutable$Map[String, String] =
immutable$Map[String, String](
)
/**
* Checks that all required fields are non-null.
*/
def validate(_item: Bar) {
if (_item.a == null) throw new TProtocolException("Required field a cannot be null")
}
override def encode(_item: Bar, _oproto: TProtocol) {
_item.write(_oproto)
}
override def decode(_iprot: TProtocol): Bar = {
var a: String = null
var _got_a = false
var b: Option[Int] = None
var _passthroughFields: Builder[(Short, TFieldBlob), immutable$Map[Short, TFieldBlob]] = null
var _done = false
_iprot.readStructBegin()
while (!_done) {
val _field = _iprot.readFieldBegin()
if (_field.`type` == TType.STOP) {
_done = true
} else {
_field.id match {
case 1 =>
_field.`type` match {
case TType.STRING => {
a = readAValue(_iprot)
_got_a = true
}
case _actualType =>
val _expectedType = TType.STRING
throw new TProtocolException(
"Received wrong type for field 'a' (expected=%s, actual=%s).".format(
ttypeToHuman(_expectedType),
ttypeToHuman(_actualType)
)
)
}
case 2 =>
_field.`type` match {
case TType.I32 => {
b = Some(readBValue(_iprot))
}
case _actualType =>
val _expectedType = TType.I32
throw new TProtocolException(
"Received wrong type for field 'b' (expected=%s, actual=%s).".format(
ttypeToHuman(_expectedType),
ttypeToHuman(_actualType)
)
)
}
case _ =>
if (_passthroughFields == null)
_passthroughFields = immutable$Map.newBuilder[Short, TFieldBlob]
_passthroughFields += (_field.id -> TFieldBlob.read(_field, _iprot))
}
_iprot.readFieldEnd()
}
}
_iprot.readStructEnd()
if (!_got_a) throw new TProtocolException("Required field 'a' was not found in serialized data for struct Bar")
new Immutable(
a,
b,
if (_passthroughFields == null)
NoPassthroughFields
else
_passthroughFields.result()
)
}
def apply(
a: String,
b: Option[Int] = None
): Bar =
new Immutable(
a,
b
)
def unapply(_item: Bar): Option[scala.Product2[String, Option[Int]]] = Some(_item)
private def readAValue(_iprot: TProtocol): String = {
_iprot.readString()
}
private def writeAField(a_item: String, _oprot: TProtocol) {
_oprot.writeFieldBegin(AField)
writeAValue(a_item, _oprot)
_oprot.writeFieldEnd()
}
private def writeAValue(a_item: String, _oprot: TProtocol) {
_oprot.writeString(a_item)
}
private def readBValue(_iprot: TProtocol): Int = {
_iprot.readI32()
}
private def writeBField(b_item: Int, _oprot: TProtocol) {
_oprot.writeFieldBegin(BField)
writeBValue(b_item, _oprot)
_oprot.writeFieldEnd()
}
private def writeBValue(b_item: Int, _oprot: TProtocol) {
_oprot.writeI32(b_item)
}
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"
}
}
object Immutable extends ThriftStructCodec3[Bar] {
override def encode(_item: Bar, _oproto: TProtocol) { _item.write(_oproto) }
override def decode(_iprot: TProtocol): Bar = Bar.decode(_iprot)
}
/**
* The default read-only implementation of Bar. You typically should not need to
* directly reference this class; instead, use the Bar.apply method to construct
* new instances.
*/
class Immutable(
val a: String,
val b: Option[Int],
override val _passthroughFields: immutable$Map[Short, TFieldBlob]
) extends Bar {
def this(
a: String,
b: Option[Int] = None
) = this(
a,
b,
Map.empty
)
}
/**
* This Proxy trait allows you to extend the Bar trait with additional state or
* behavior and implement the read-only methods from Bar using an underlying
* instance.
*/
trait Proxy extends Bar {
protected def _underlying_Bar: Bar
override def a: String = _underlying_Bar.a
override def b: Option[Int] = _underlying_Bar.b
override def _passthroughFields = _underlying_Bar._passthroughFields
}
}
trait Bar
extends ThriftStruct
with scala.Product2[String, Option[Int]]
with java.io.Serializable
{
import Bar._
def a: String
def b: Option[Int]
def _passthroughFields: immutable$Map[Short, TFieldBlob] = immutable$Map.empty
def _1 = a
def _2 = b
/**
* Gets a field value encoded as a binary blob using TCompactProtocol. If the specified field
* is present in the passthrough map, that value is returend. Otherwise, if the specified field
* is known and not optional and set to None, then the field is serialized and returned.
*/
def getFieldBlob(_fieldId: Short): Option[TFieldBlob] = {
lazy val _buff = new TMemoryBuffer(32)
lazy val _oprot = new TCompactProtocol(_buff)
_passthroughFields.get(_fieldId) orElse {
val _fieldOpt: Option[TField] =
_fieldId match {
case 1 =>
if (a ne null) {
writeAValue(a, _oprot)
Some(Bar.AField)
} else {
None
}
case 2 =>
if (b.isDefined) {
writeBValue(b.get, _oprot)
Some(Bar.BField)
} else {
None
}
case _ => None
}
_fieldOpt match {
case Some(_field) =>
val _data = Arrays.copyOfRange(_buff.getArray, 0, _buff.length)
Some(TFieldBlob(_field, _data))
case None =>
None
}
}
}
/**
* Collects TCompactProtocol-encoded field values according to `getFieldBlob` into a map.
*/
def getFieldBlobs(ids: TraversableOnce[Short]): immutable$Map[Short, TFieldBlob] =
(ids flatMap { id => getFieldBlob(id) map { id -> _ } }).toMap
/**
* Sets a field using a TCompactProtocol-encoded binary blob. If the field is a known
* field, the blob is decoded and the field is set to the decoded value. If the field
* is unknown and passthrough fields are enabled, then the blob will be stored in
* _passthroughFields.
*/
def setField(_blob: TFieldBlob): Bar = {
var a: String = this.a
var b: Option[Int] = this.b
var _passthroughFields = this._passthroughFields
_blob.id match {
case 1 =>
a = readAValue(_blob.read)
case 2 =>
b = Some(readBValue(_blob.read))
case _ => _passthroughFields += (_blob.id -> _blob)
}
new Immutable(
a,
b,
_passthroughFields
)
}
/**
* If the specified field is optional, it is set to None. Otherwise, if the field is
* known, it is reverted to its default value; if the field is unknown, it is subtracked
* from the passthroughFields map, if present.
*/
def unsetField(_fieldId: Short): Bar = {
var a: String = this.a
var b: Option[Int] = this.b
_fieldId match {
case 1 =>
a = null
case 2 =>
b = None
case _ =>
}
new Immutable(
a,
b,
_passthroughFields - _fieldId
)
}
/**
* If the specified field is optional, it is set to None. Otherwise, if the field is
* known, it is reverted to its default value; if the field is unknown, it is subtracked
* from the passthroughFields map, if present.
*/
def unsetA: Bar = unsetField(1)
def unsetB: Bar = unsetField(2)
override def write(_oprot: TProtocol) {
Bar.validate(this)
_oprot.writeStructBegin(Struct)
if (a ne null) writeAField(a, _oprot)
if (b.isDefined) writeBField(b.get, _oprot)
_passthroughFields.values foreach { _.write(_oprot) }
_oprot.writeFieldStop()
_oprot.writeStructEnd()
}
def copy(
a: String = this.a,
b: Option[Int] = this.b,
_passthroughFields: immutable$Map[Short, TFieldBlob] = this._passthroughFields
): Bar =
new Immutable(
a,
b,
_passthroughFields
)
override def canEqual(other: Any): Boolean = other.isInstanceOf[Bar]
override def equals(other: Any): Boolean =
_root_.scala.runtime.ScalaRunTime._equals(this, other) &&
_passthroughFields == other.asInstanceOf[Bar]._passthroughFields
override def hashCode: Int = _root_.scala.runtime.ScalaRunTime._hashCode(this)
override def toString: String = _root_.scala.runtime.ScalaRunTime._toString(this)
override def productArity: Int = 2
override def productElement(n: Int): Any = n match {
case 0 => this.a
case 1 => this.b
case _ => throw new IndexOutOfBoundsException(n.toString)
}
override def productPrefix: String = "Bar"
}
/**
* Generated by Scrooge
* version: 3.16.3
* rev: b8593c83072d94fc44feaa8d97940b9266d84ed0
* built at: 20140806-054445
*/
package com.mycorp
import com.twitter.scrooge.{
TFieldBlob, ThriftException, ThriftStruct, ThriftStructCodec3, ThriftStructFieldInfo, ThriftUtil}
import org.apache.thrift.protocol._
import org.apache.thrift.transport.{TMemoryBuffer, TTransport}
import java.nio.ByteBuffer
import java.util.Arrays
import scala.collection.immutable.{Map => immutable$Map}
import scala.collection.mutable.Builder
import scala.collection.mutable.{
ArrayBuffer => mutable$ArrayBuffer, Buffer => mutable$Buffer,
HashMap => mutable$HashMap, HashSet => mutable$HashSet}
import scala.collection.{Map, Set}
object Foo extends ThriftStructCodec3[Foo] {
private val NoPassthroughFields = immutable$Map.empty[Short, TFieldBlob]
val Struct = new TStruct("Foo")
val CField = new TField("c", TType.STRUCT, 1)
val CFieldManifest = implicitly[Manifest[Bar]]
val DField = new TField("d", TType.BOOL, 2)
val DFieldManifest = implicitly[Manifest[Boolean]]
/**
* Field information in declaration order.
*/
lazy val fieldInfos: scala.List[ThriftStructFieldInfo] = scala.List[ThriftStructFieldInfo](
new ThriftStructFieldInfo(
CField,
false,
CFieldManifest,
None,
None,
immutable$Map(
),
immutable$Map(
)
),
new ThriftStructFieldInfo(
DField,
true,
DFieldManifest,
None,
None,
immutable$Map(
),
immutable$Map(
)
)
)
lazy val structAnnotations: immutable$Map[String, String] =
immutable$Map[String, String](
)
/**
* Checks that all required fields are non-null.
*/
def validate(_item: Foo) {
if (_item.c == null) throw new TProtocolException("Required field c cannot be null")
}
override def encode(_item: Foo, _oproto: TProtocol) {
_item.write(_oproto)
}
override def decode(_iprot: TProtocol): Foo = {
var c: Bar = null
var _got_c = false
var d: Option[Boolean] = None
var _passthroughFields: Builder[(Short, TFieldBlob), immutable$Map[Short, TFieldBlob]] = null
var _done = false
_iprot.readStructBegin()
while (!_done) {
val _field = _iprot.readFieldBegin()
if (_field.`type` == TType.STOP) {
_done = true
} else {
_field.id match {
case 1 =>
_field.`type` match {
case TType.STRUCT => {
c = readCValue(_iprot)
_got_c = true
}
case _actualType =>
val _expectedType = TType.STRUCT
throw new TProtocolException(
"Received wrong type for field 'c' (expected=%s, actual=%s).".format(
ttypeToHuman(_expectedType),
ttypeToHuman(_actualType)
)
)
}
case 2 =>
_field.`type` match {
case TType.BOOL => {
d = Some(readDValue(_iprot))
}
case _actualType =>
val _expectedType = TType.BOOL
throw new TProtocolException(
"Received wrong type for field 'd' (expected=%s, actual=%s).".format(
ttypeToHuman(_expectedType),
ttypeToHuman(_actualType)
)
)
}
case _ =>
if (_passthroughFields == null)
_passthroughFields = immutable$Map.newBuilder[Short, TFieldBlob]
_passthroughFields += (_field.id -> TFieldBlob.read(_field, _iprot))
}
_iprot.readFieldEnd()
}
}
_iprot.readStructEnd()
if (!_got_c) throw new TProtocolException("Required field 'c' was not found in serialized data for struct Foo")
new Immutable(
c,
d,
if (_passthroughFields == null)
NoPassthroughFields
else
_passthroughFields.result()
)
}
def apply(
c: Bar,
d: Option[Boolean] = None
): Foo =
new Immutable(
c,
d
)
def unapply(_item: Foo): Option[scala.Product2[Bar, Option[Boolean]]] = Some(_item)
private def readCValue(_iprot: TProtocol): Bar = {
com.gu.contentapi.porter.integration.flexible.model.v1.Bar.decode(_iprot)
}
private def writeCField(c_item: Bar, _oprot: TProtocol) {
_oprot.writeFieldBegin(CField)
writeCValue(c_item, _oprot)
_oprot.writeFieldEnd()
}
private def writeCValue(c_item: Bar, _oprot: TProtocol) {
c_item.write(_oprot)
}
private def readDValue(_iprot: TProtocol): Boolean = {
_iprot.readBool()
}
private def writeDField(d_item: Boolean, _oprot: TProtocol) {
_oprot.writeFieldBegin(DField)
writeDValue(d_item, _oprot)
_oprot.writeFieldEnd()
}
private def writeDValue(d_item: Boolean, _oprot: TProtocol) {
_oprot.writeBool(d_item)
}
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"
}
}
object Immutable extends ThriftStructCodec3[Foo] {
override def encode(_item: Foo, _oproto: TProtocol) { _item.write(_oproto) }
override def decode(_iprot: TProtocol): Foo = Foo.decode(_iprot)
}
/**
* The default read-only implementation of Foo. You typically should not need to
* directly reference this class; instead, use the Foo.apply method to construct
* new instances.
*/
class Immutable(
val c: Bar,
val d: Option[Boolean],
override val _passthroughFields: immutable$Map[Short, TFieldBlob]
) extends Foo {
def this(
c: Bar,
d: Option[Boolean] = None
) = this(
c,
d,
Map.empty
)
}
/**
* This Proxy trait allows you to extend the Foo trait with additional state or
* behavior and implement the read-only methods from Foo using an underlying
* instance.
*/
trait Proxy extends Foo {
protected def _underlying_Foo: Foo
override def c: Bar = _underlying_Foo.c
override def d: Option[Boolean] = _underlying_Foo.d
override def _passthroughFields = _underlying_Foo._passthroughFields
}
}
trait Foo
extends ThriftStruct
with scala.Product2[Bar, Option[Boolean]]
with java.io.Serializable
{
import Foo._
def c: Bar
def d: Option[Boolean]
def _passthroughFields: immutable$Map[Short, TFieldBlob] = immutable$Map.empty
def _1 = c
def _2 = d
/**
* Gets a field value encoded as a binary blob using TCompactProtocol. If the specified field
* is present in the passthrough map, that value is returend. Otherwise, if the specified field
* is known and not optional and set to None, then the field is serialized and returned.
*/
def getFieldBlob(_fieldId: Short): Option[TFieldBlob] = {
lazy val _buff = new TMemoryBuffer(32)
lazy val _oprot = new TCompactProtocol(_buff)
_passthroughFields.get(_fieldId) orElse {
val _fieldOpt: Option[TField] =
_fieldId match {
case 1 =>
if (c ne null) {
writeCValue(c, _oprot)
Some(Foo.CField)
} else {
None
}
case 2 =>
if (d.isDefined) {
writeDValue(d.get, _oprot)
Some(Foo.DField)
} else {
None
}
case _ => None
}
_fieldOpt match {
case Some(_field) =>
val _data = Arrays.copyOfRange(_buff.getArray, 0, _buff.length)
Some(TFieldBlob(_field, _data))
case None =>
None
}
}
}
/**
* Collects TCompactProtocol-encoded field values according to `getFieldBlob` into a map.
*/
def getFieldBlobs(ids: TraversableOnce[Short]): immutable$Map[Short, TFieldBlob] =
(ids flatMap { id => getFieldBlob(id) map { id -> _ } }).toMap
/**
* Sets a field using a TCompactProtocol-encoded binary blob. If the field is a known
* field, the blob is decoded and the field is set to the decoded value. If the field
* is unknown and passthrough fields are enabled, then the blob will be stored in
* _passthroughFields.
*/
def setField(_blob: TFieldBlob): Foo = {
var c: Bar = this.c
var d: Option[Boolean] = this.d
var _passthroughFields = this._passthroughFields
_blob.id match {
case 1 =>
c = readCValue(_blob.read)
case 2 =>
d = Some(readDValue(_blob.read))
case _ => _passthroughFields += (_blob.id -> _blob)
}
new Immutable(
c,
d,
_passthroughFields
)
}
/**
* If the specified field is optional, it is set to None. Otherwise, if the field is
* known, it is reverted to its default value; if the field is unknown, it is subtracked
* from the passthroughFields map, if present.
*/
def unsetField(_fieldId: Short): Foo = {
var c: Bar = this.c
var d: Option[Boolean] = this.d
_fieldId match {
case 1 =>
c = null
case 2 =>
d = None
case _ =>
}
new Immutable(
c,
d,
_passthroughFields - _fieldId
)
}
/**
* If the specified field is optional, it is set to None. Otherwise, if the field is
* known, it is reverted to its default value; if the field is unknown, it is subtracked
* from the passthroughFields map, if present.
*/
def unsetC: Foo = unsetField(1)
def unsetD: Foo = unsetField(2)
override def write(_oprot: TProtocol) {
Foo.validate(this)
_oprot.writeStructBegin(Struct)
if (c ne null) writeCField(c, _oprot)
if (d.isDefined) writeDField(d.get, _oprot)
_passthroughFields.values foreach { _.write(_oprot) }
_oprot.writeFieldStop()
_oprot.writeStructEnd()
}
def copy(
c: Bar = this.c,
d: Option[Boolean] = this.d,
_passthroughFields: immutable$Map[Short, TFieldBlob] = this._passthroughFields
): Foo =
new Immutable(
c,
d,
_passthroughFields
)
override def canEqual(other: Any): Boolean = other.isInstanceOf[Foo]
override def equals(other: Any): Boolean =
_root_.scala.runtime.ScalaRunTime._equals(this, other) &&
_passthroughFields == other.asInstanceOf[Foo]._passthroughFields
override def hashCode: Int = _root_.scala.runtime.ScalaRunTime._hashCode(this)
override def toString: String = _root_.scala.runtime.ScalaRunTime._toString(this)
override def productArity: Int = 2
override def productElement(n: Int): Any = n match {
case 0 => this.c
case 1 => this.d
case _ => throw new IndexOutOfBoundsException(n.toString)
}
override def productPrefix: String = "Foo"
}
struct Bar {
1: required string a
2: optional i32 b
}
struct Foo {
1: required Bar c
2: optional bool d
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment