Support for defining extra structure on the output of the case class
I am using the case classes generated by ScalaBuff as a "Command/Event" message into and out of an EventSourced application. Inside the ES application storage layer, they get serialised using protobuf, but as it happens they also form the API on the Web Interfaces (internal and / or external).
XML --> (Deserialise XML to CaseClass) --> DoWork --> Persist CC using protobuf
The "serialisation" of the Case Class coming "into" the system, for example can be from XML, using JAXB annotation, and deserialised into a case class. FasterXML Jackson also supports JSON de/serialisation. So a single case class annotated is both XML and JSON, just by the annotations on the fields.
An example of a normal annotated case class is as follows:
@XmlRootElement(name = "company") @XmlAccessorType(XmlAccessType.FIELD) case class Company ( @xmlAttribute(required = true) uuid: String, @xmlAttribute(required = false) version: Long = -1, @xmlAttribute(required = true) id: Long, @xmlAttribute(required = true) name: String, @xmlAttribute(required = true) active: Boolean ) extends BaseEntity
The annotations may vary, but in essence, they are field level on the constructor, and class level at the top.
It would be great to have a way to mark the "protobuf" message .proto file, to carry these annotations right through to case class generation.
The hope is to preserve DRY.
Any thoughts to how you might go about this ? I am happy to help implement it.
The only way to mark a proto file is using specially-crafted comments, since anything else would require a protoc extension, ie. it would be incompatible with protoc and third party language generators.
Alternatively, if you just want these annotations directly generated from the actual protoc file, in other words you just want to pass a boolean flag (--generateJAXB or --maximize-ugliness :D) to ScalaBuff, that can be done relatively easily and without introducing any incompatibilities.
If I understand this correctly, the XmlRootElement should be generated once with a name equal to the lowercase case class name, and each field should have a required, optional or repeated attribute that is equal to the relevant field type. In short, all of this data is equal to the actual protoc data. If you want me to implement this, please give me a more concrete example, listing all possible generated XML annotations with relevant attributes. Thanks.
I have not looked into it, but does ScalaBuff use a Template file for the case class ?
Supporting templates of the generated case class would be quite powerful,
I used a similar technique, vannitator, -- a small library I created .. (Java Annotated Class --> anything Generation)
The class is annotated - and it denotes a template file to used to "create" the class. (or something else) Support for an alternative template (such as one that has custom JAXB annotations) would be powerful
@Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @VannitateManyToOne(annotation = "samples.annotations.SampleOneToOne", templateName = "samples/SampleManyToOne.ftl") public @interface SampleManyToOne {
/**
* The name of your request factory
*/
String newClassName();
}
https://code.google.com/p/vannitator/source/browse/trunk/vannitator-gwt/src/main/resources/org/soqqo/vannitator/annotation/gwt/GenRequestFactory.ftl
Of course .. this is subtly different, the "source" is an annotated Java Class, the template then can be anything.
In ScalaBuff case, the source is a "message.proto" file, the "output" is a Scala Case Class.
Ramon Buckland [email protected]
On 8 Mar 2013, at 20:31, Sandro Gržičić [email protected] wrote:
The only way to mark a proto file is using comments, since anything else would require a protoc extension, ie. it would be incompatible with protoc and third party language generators.
Alternatively, if you just want these annotations directly generated from the actual protoc file, in other words you just want to pass a boolean flag (--generateJAXB) to ScalaBuff, that can be done relatively easily and without introducing any incompatibilities.
— Reply to this email directly or view it on GitHub.
So looking at the Generator - it is not template based. It "could be".. i'll look at it a bit more later.
https://github.com/SandroGrzicic/ScalaBuff/blob/master/scalabuff-compiler/src/main/net/sandrogrzicic/scalabuff/compiler/Generator.scala
I don't think ScalaBuff should turn into a kitchen-sink for template transformations. Its purpose is to generate Scala case classes from .proto files to avoid both having to install the native protoc and to be able to have nicer generated classes than protoc.
On principal I agree - it should do the job and do it well. I would add however, that someone may desire a different type of Scala Class "to" protobuf model. In this case, to support a case class and the "other" would mean two Generators.
A feature, where the default template is the scala case class output, and the option to supply a "different" template would be very powerful.
It's task should always be "from .proto - to Scala"
I could split the big generate method into smaller submethods, each generating a separate output case class method so that Generator could be subclassed if you want to make a different type of a case class but still use most of the default stuff. I could even write the JaxbGenerator for you if you can provide me the details I requested.
However, I'm not really sure about the whole "template" system, I think it would overcomplicate case class generation.