Re-adds Fixes WAVE-435, Refactoring of PST compiler and general cleanup 
https://reviews.apache.org/r/42114


Project: http://git-wip-us.apache.org/repos/asf/incubator-wave/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-wave/commit/36445930
Tree: http://git-wip-us.apache.org/repos/asf/incubator-wave/tree/36445930
Diff: http://git-wip-us.apache.org/repos/asf/incubator-wave/diff/36445930

Branch: refs/heads/master
Commit: 3644593073099d207aff1d878387b35ff79045ab
Parents: ee2dadf
Author: yuri.zelikov <[email protected]>
Authored: Tue Jan 12 10:10:40 2016 +0200
Committer: yuri.zelikov <[email protected]>
Committed: Tue Jan 12 10:10:40 2016 +0200

----------------------------------------------------------------------
 .gitignore                                      |   2 +-
 build.gradle                                    | 160 ++---
 pst/LICENSE                                     | 235 +++++++
 pst/build.gradle                                | 224 +++++-
 pst/src/dist/LICENSE                            | 244 +++++++
 pst/src/dist/NOTICE                             |   8 +
 pst/src/main/java/org/apache/wave/pst/Pst.java  | 189 +++++
 .../org/apache/wave/pst/PstCommandLine.java     | 151 ++++
 .../java/org/apache/wave/pst/PstException.java  |  67 ++
 .../org/apache/wave/pst/PstFileDescriptor.java  | 345 ++++++++++
 .../main/java/org/apache/wave/pst/PstMain.java  |  92 +++
 .../org/apache/wave/pst/model/EnumValue.java    |  60 ++
 .../java/org/apache/wave/pst/model/Field.java   | 283 ++++++++
 .../java/org/apache/wave/pst/model/Message.java | 343 +++++++++
 .../wave/pst/model/MessageProperties.java       | 112 +++
 .../org/apache/wave/pst/model/ProtoEnum.java    | 140 ++++
 .../java/org/apache/wave/pst/model/Type.java    | 244 +++++++
 .../java/org/apache/wave/pst/model/Util.java    |  46 ++
 .../org/apache/wave/pst/style/PstStyler.java    | 513 ++++++++++++++
 .../java/org/apache/wave/pst/style/Styler.java  |  45 ++
 .../pst/testing/RandomProtobufGenerator.java    | 170 +++++
 pst/src/main/java/org/waveprotocol/pst/Pst.java | 188 -----
 .../org/waveprotocol/pst/PstCommandLine.java    | 150 ----
 .../java/org/waveprotocol/pst/PstException.java |  67 --
 .../org/waveprotocol/pst/PstFileDescriptor.java | 345 ----------
 .../main/java/org/waveprotocol/pst/PstMain.java |  92 ---
 .../org/waveprotocol/pst/model/EnumValue.java   |  60 --
 .../java/org/waveprotocol/pst/model/Field.java  | 283 --------
 .../org/waveprotocol/pst/model/Message.java     | 343 ---------
 .../pst/model/MessageProperties.java            | 112 ---
 .../org/waveprotocol/pst/model/ProtoEnum.java   | 140 ----
 .../java/org/waveprotocol/pst/model/Type.java   | 244 -------
 .../java/org/waveprotocol/pst/model/Util.java   |  46 --
 .../org/waveprotocol/pst/style/PstStyler.java   | 513 --------------
 .../java/org/waveprotocol/pst/style/Styler.java |  45 --
 .../pst/testing/RandomProtobufGenerator.java    | 170 -----
 .../main/proto/google/protobuf/descriptor.proto | 687 +++++++++++++++++++
 .../apache/wave/pst/protobuf/extensions.proto   |  34 +
 release/artifact-sign.sh                        |  27 -
 scripts/vagrant/setup-fedora.sh                 |   2 +-
 scripts/vagrant/setup-ubuntu.sh                 |   2 +-
 settings.gradle                                 |   2 +-
 sonar-project.properties                        |  22 +
 wave-proto/build.gradle                         |  46 --
 .../main/proto/google/protobuf/descriptor.proto | 687 -------------------
 .../proto/google/protobuf/descriptor.proto.v2.5 | 420 ------------
 .../box/attachment/attachment.proto             |  50 --
 .../box/common/comms/waveclient-rpc.proto       | 199 ------
 .../org/waveprotocol/box/profile/profiles.proto |  51 --
 .../org/waveprotocol/box/search/search.proto    |  68 --
 .../persistence/protos/account-store.proto      |  78 ---
 .../server/persistence/protos/delta-store.proto |  38 -
 .../org/waveprotocol/box/server/rpc/rpc.proto   |  66 --
 .../proto/org/waveprotocol/protobuf/build.xml   |  27 -
 .../org/waveprotocol/protobuf/extensions.proto  |  34 -
 .../wave/concurrencycontrol/clientserver.proto  | 268 --------
 .../proto/org/waveprotocol/wave/diff/build.xml  |  28 -
 .../proto/org/waveprotocol/wave/diff/diff.proto | 114 ---
 .../wave/federation/federation.protodevel       | 247 -------
 .../wave/federation/federation_error.protodevel |  81 ---
 wave/build.gradle                               | 402 ++++++-----
 .../box/attachment/attachment.proto             |  50 ++
 .../box/common/comms/waveclient-rpc.proto       | 199 ++++++
 .../org/waveprotocol/box/profile/profiles.proto |  51 ++
 .../org/waveprotocol/box/search/search.proto    |  68 ++
 .../persistence/protos/account-store.proto      |  78 +++
 .../server/persistence/protos/delta-store.proto |  38 +
 .../org/waveprotocol/box/server/rpc/rpc.proto   |  66 ++
 .../wave/concurrencycontrol/clientserver.proto  | 268 ++++++++
 .../proto/org/waveprotocol/wave/diff/build.xml  |  28 +
 .../proto/org/waveprotocol/wave/diff/diff.proto | 114 +++
 .../wave/federation/federation.protodevel       | 247 +++++++
 .../wave/federation/federation_error.protodevel |  81 +++
 73 files changed, 5822 insertions(+), 5617 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index dafa041..b3db961 100755
--- a/.gitignore
+++ b/.gitignore
@@ -48,7 +48,7 @@ distributions/
 ### Reports
 reports/
 ### Generated Sources
-wave/src/generated/
+**/generated/
 ### Gwt Testing
 wave/gwt-unitCache
 ### config

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index a96142d..2f445c9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,64 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//=============================================================================
+// Plugins
+//=============================================================================
 buildscript {
+    repositories {
+        mavenCentral()
+    }
     dependencies {
-        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.0'
+        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.3'
     }
 }
-
 plugins {
     id "org.nosphere.apache.rat" version "0.2.0"
-    id "org.sonarqube" version "1.1"
 }
-
 allprojects {
     apply plugin: 'eclipse';
     apply plugin: 'idea';
     apply plugin: 'jacoco'
     group = 'apache-wave'
-    version = '0.4'
-}
-
-// Repositories
-repositories {
-    mavenCentral()
-}
-
-subprojects {
-    apply plugin: 'java';
-    //apply plugin: 'scala';
-    //apply plugin: 'checkstyle'
-    sourceCompatibility = 1.7
-    targetCompatibility = 1.7
-    test.ignoreFailures = true
-
-    compileJava{
-        options.incremental = true
-    }
-
-    task sourcesJar(type: Jar, dependsOn: classes) {
-        classifier = 'sources'
-        from sourceSets.main.allSource
-    }
-}
-
-project(':wave'){
-    dependencies {
-        compile project(':pst')
-    }
 }
 
-project(':pst'){
-    dependencies {
-        compile project(':wave-proto')
-    }
-}
+//=============================================================================
+// Project Level Settings
+//=============================================================================
+version = 0.4 //only applies to the wave server & client, should be changed 
once split
 
-// Apache Rat Plugin
+//=============================================================================
+// Apache Rat Configuration
+//=============================================================================
 rat {
-    // Input directory, defaults to '.'
     inputDir = '.'
-    // XML and HTML reports directory, defaults to project.buildDir + 
'/reports/rat'
     reportDir = project.file('reports/rat')
-    // List of exclude directives, defaults to ['**/.gradle/**']
     excludes = [
             '**/build/**',
             'reports/**',
@@ -69,10 +57,8 @@ rat {
             '**/*.iml',
             '**/generated/**'
     ]
-    // Fail the build on rat errors, defaults to true
     failOnError = false
 }
-
 rat.doFirst {
     println ''
     println '----------------------------------------------'
@@ -82,62 +68,51 @@ rat.doFirst {
     println ''
 }
 
+//=============================================================================
+// Source Distribution
+//=============================================================================
+
+def srcName = this.group + "-src-" + this.version
+def srcExcludes = [
+        'distributions/',
+        '.gradle/',
+        '.git/',
+        '.vagrant/',
+        '*/build/*',
+        '*/_*',
+        '*/gwt-unitCache/',
+        '*.iml',
+        '*/*.iml',
+        '*.iws',
+        '*.ipr',
+        '*.project',
+        '*/*.project',
+        '*/*.classpath',
+        '*/.settings/',
+        '*/*.log*',
+        'reports/',
+        'wave/war/WEB-INF',
+        'wave/war/webclient'
+]
+
 task createDistSourceZip(type: Zip) {
-    baseName = this.group + "-src-" + this.version
+    baseName = srcName
     destinationDir = file('distributions')
     from('./') {
         into 'apache-wave-src'
     }
-    excludes = [
-            'distributions/',
-            '.gradle/',
-            '.git/',
-            '.vagrant/',
-            '*/build/*',
-            '*/_*',
-            '*/gwt-unitCache/',
-            '*.iml',
-            '*/*.iml',
-            '*.iws',
-            '*.ipr',
-            '*.project',
-            '*/*.project',
-            '*/*.classpath',
-            '*/.settings/',
-            '*/*.log*',
-            'reports/',
-            'wave/war/WEB-INF',
-            'wave/war/webclient'
-    ]
+    excludes = srcExcludes
 }
 
 task createDistSourceTar(type: Tar) {
-    baseName = this.group + "-src-" + this.version
+    compression = Compression.GZIP
+    extension = 'tar.gz'
+    baseName = srcName
     destinationDir = file('distributions')
     from('./') {
         into 'apache-wave-src'
     }
-    excludes = [
-            'distributions/',
-            '.gradle/',
-            '.git/',
-            '.vagrant/',
-            '*/build/*',
-            '*/_*',
-            '*/gwt-unitCache/',
-            '*.iml',
-            '*/*.iml',
-            '*.iws',
-            '*.ipr',
-            '*.project',
-            '*/*.project',
-            '*/*.classpath',
-            '*/.settings/',
-            '*/*.log*',
-            'reports/',
-            'wave/war/WEB-INF',
-            'wave/war/webclient'
-    ]
+    excludes = srcExcludes
 }
 
 task createDistSource() {
@@ -150,8 +125,11 @@ task createDistSource() {
     }
 }
 
-createDistSource.dependsOn createDistSourceZip, createDistSourceTar
+createDistSource.dependsOn createDistSourceZip, createDistSourceTar, 
":pst:createDistSource"
 
+//=============================================================================
+// Distribution's
+//=============================================================================
 task createDist() {
     doFirst {
         println ''
@@ -163,4 +141,4 @@ task createDist() {
     }
 }
 
-createDist.dependsOn createDistSource, ":wave:createDistBin"
\ No newline at end of file
+createDist.dependsOn createDistSource, ":wave:createDistBin", ":pst:createDist"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/LICENSE
----------------------------------------------------------------------
diff --git a/pst/LICENSE b/pst/LICENSE
new file mode 100644
index 0000000..1dd0347
--- /dev/null
+++ b/pst/LICENSE
@@ -0,0 +1,235 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2013 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+***THE FOLLOWING LICENSE APPLIES TO***
+- Protobuf Descriptors located at /src/google/protobuf/descriptor.proto
+
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.  All rights reserved.
+http://code.google.com/p/protobuf/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/build.gradle
----------------------------------------------------------------------
diff --git a/pst/build.gradle b/pst/build.gradle
index 530ee83..0e53b8b 100644
--- a/pst/build.gradle
+++ b/pst/build.gradle
@@ -1,34 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//=============================================================================
 // Plugins
-apply plugin: 'java'
+//=============================================================================
+plugins {
+    id 'java'
+    id 'com.github.johnrengelman.shadow' version '1.2.2'
+}
+apply plugin: 'com.google.protobuf'
 
-// Settings
+//=============================================================================
+// Project Level Settings
+//=============================================================================
 version = 0.1
+sourceCompatibility = 1.7
+targetCompatibility = 1.7
+def title = 'Apache Wave PST Compiler'
+def vendor = 'The Apache Software Foundation'
 
-// Dependencies
-repositories {
-    mavenCentral()
-}
-
-// - Project - Compile
-dependencies {
-    compile group: 'com.google.protobuf', name: 'protobuf-java', version: 
'2.6.1'
-    compile group: 'com.google.guava', name: 'guava', version: '15.0'
-    compile group: 'org.antlr', name: 'antlr', version: '3.2'
-    compile group: 'commons-cli', name: 'commons-cli', version: '1.2'
-    compile fileTree(dir: '../wave-proto/build/libs', include: "**/*.jar")
-// - Project - Testing
-    testCompile group: 'junit', name: 'junit', version: '4.11'
+jar {
+    manifest {
+        attributes "Specification-Vendor": vendor,
+                "Specification-Title": title,
+                "Specification-Version": version,
+                "Implementation-Vendor": vendor,
+                "Implementation-Title": title,
+                "Implementation-Version": version,
+                "Built-By": "No one in particular",
+                "Main-Class": "org.apache.wave.pst.PstMain"
+    }
 }
 
-// Source Sets
+//=============================================================================
+// Source's
+//=============================================================================
 sourceSets {
     main {
         java {
-            srcDir 'src/main/java'
-            //srcDir '../wave-proto/build/classes/main/'
+            srcDirs = [
+                    'src/main/java',
+                    'generated/main/java'
+            ]
         }
-        resources {
-            srcDir 'src/main/resources'
+        proto {
+            srcDir 'src/main/proto'
         }
     }
 
@@ -36,8 +66,152 @@ sourceSets {
         java {
             srcDir 'src/test/java'
         }
-        resources {
-            srcDir 'src/test/resources'
-        }
     }
-}
\ No newline at end of file
+}
+
+//=============================================================================
+// Dependencies
+// Note: next to each dependency is a review stamp [last review, next review].
+//       If a dependency is past its review date pls create a jira issue.
+//       https://issues.apache.org/jira/browse/WAVE
+//=============================================================================
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile group: 'com.google.protobuf', name: 'protobuf-java', version: 
'2.6.1' // [12/2015, 3/2016]
+    compile group: 'com.google.guava', name: 'guava', version: '19.0'          
   // [1/2016, 6/2016]
+    compile group: 'org.antlr', name: 'antlr', version: '3.2'                  
   // [12/2015, 3/2016]
+    compile group: 'commons-cli', name: 'commons-cli', version: '1.3.1'        
   // [1/2016, 6/2016]
+
+    testCompile group: 'junit', name: 'junit', version: '4.12'                 
   // [1/2016, 1/2017]
+}
+
+//=============================================================================
+// Protobuf Config
+//=============================================================================
+protobuf {
+    protoc {
+        artifact = 'com.google.protobuf:protoc:2.6.1'
+    }
+    generatedFilesBaseDir = "$projectDir/generated"
+}
+
+//=============================================================================
+// UberJar (shadowJar) config
+//=============================================================================
+
+shadowJar {
+    baseName = 'wave-pst'
+    classifier = ''
+    exclude 'META-INF/**/*'
+}
+
+//=============================================================================
+// Clean - Must remove generated sources.
+//=============================================================================
+clean {
+    delete "generated/"
+}
+
+//=============================================================================
+// Source Distribution
+//=============================================================================
+
+def srcName = this.group + "-" + this.name + "-src"
+def srcExcludes = [
+        'build/*',
+        '*.iml'
+]
+
+task createDistSourceTar(type: Tar) {
+    compression = Compression.GZIP
+    extension = 'tar.gz'
+    baseName = srcName
+    destinationDir = file('../distributions')
+    from('./') {
+        into 'apache-wave-pst-src'
+    }
+    excludes = srcExcludes
+
+}
+
+task createDistSourceZip(type: Zip) {
+    baseName = srcName
+    destinationDir = file('../distributions')
+    from('./') {
+        into 'apache-wave-pst-src'
+    }
+    excludes = srcExcludes
+}
+
+task createDistSource() {
+    doFirst {
+        println ''
+        println '--------------------------------------------------------'
+        println '     Creating Deployment Source - Apache Wave PST       '
+        println '--------------------------------------------------------'
+        println ''
+    }
+}
+
+createDistSource.dependsOn createDistSourceTar, createDistSourceZip
+
+//=============================================================================
+// Binary Distribution
+//=============================================================================
+
+def binName = this.group + "-" + this.name + "-bin"
+
+task createDistBinTar(type: Tar) {
+    compression = Compression.GZIP
+    extension = 'tar.gz'
+    baseName = binName
+    destinationDir = file('../distributions')
+    from(shadowJar) {
+        into 'apache-wave-pst/bin'
+    }
+    from('src/dist') {
+        into 'apache-wave-pst'
+    }
+}
+
+task createDistBinZip(type: Zip) {
+    baseName = binName
+    destinationDir = file('../distributions')
+    from(shadowJar) {
+        into 'apache-wave-pst/bin'
+    }
+    from('src/dist') {
+        into 'apache-wave-pst'
+    }
+}
+
+task createDistBin() {
+    doFirst {
+        println ''
+        println '--------------------------------------------------------'
+        println '     Creating Deployment Binary - Apache Wave PST       '
+        println '--------------------------------------------------------'
+        println ''
+    }
+}
+
+createDistBin.dependsOn createDistBinTar, createDistBinZip
+
+//=============================================================================
+// Distribution's
+//=============================================================================
+
+task createDist() {
+    doFirst {
+        println ''
+        println '--------------------------------------------------------'
+        println '      Creating Deployments - Apache Wave PST            '
+        println '--------------------------------------------------------'
+        println ''
+    }
+}
+
+createDist.dependsOn createDistSource, createDistBin
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/dist/LICENSE
----------------------------------------------------------------------
diff --git a/pst/src/dist/LICENSE b/pst/src/dist/LICENSE
new file mode 100644
index 0000000..c60ce90
--- /dev/null
+++ b/pst/src/dist/LICENSE
@@ -0,0 +1,244 @@
+ ***THE FOLLOWING LICENSE APPLIES TO***
+- Apache Wave PST
+- Apache Commons CLI included in the generated jar files
+- Google Guava included in the generated jar files
+
+                                Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2013 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+***THE FOLLOWING LICENSE APPLIES TO***
+- Protobuf Java libraries included in the generated jar files
+
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.
+

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/dist/NOTICE
----------------------------------------------------------------------
diff --git a/pst/src/dist/NOTICE b/pst/src/dist/NOTICE
new file mode 100644
index 0000000..ac0e02a
--- /dev/null
+++ b/pst/src/dist/NOTICE
@@ -0,0 +1,8 @@
+   Apache Wave - PST
+   Copyright 2011-2016 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Portions of this software were developed at Google Inc. and
+   have been kindly donated to the Apache Software Foundation.

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/Pst.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/Pst.java 
b/pst/src/main/java/org/apache/wave/pst/Pst.java
new file mode 100644
index 0000000..1265899
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/Pst.java
@@ -0,0 +1,189 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FileDescriptor;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.antlr.stringtemplate.StringTemplateGroup;
+
+import org.apache.wave.pst.model.Message;
+import org.apache.wave.pst.model.MessageProperties;
+import org.apache.wave.pst.style.Styler;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * PST stands for protobuf-stringtemplate.
+ *
+ * The tool allows arbitrary code generation given a series of string
+ * templates, each passed the description of a protocol buffer file. This 
allows
+ * protobuf- based file generation beyond what existing protocol compilers
+ * (protoc, protostuff, etc) are capable of (without modification), using the
+ * convenience and safety of <a href="http://stringtemplate.org";>string
+ * template</a>.
+ *
+ * A number of sample templates are bundles (in templates), so see these as
+ * examples. These templates give a complete client/server JSON message stack:
+ * <ul>
+ * <li><em>message</em> is a common interface.</li>
+ * <li><em>messageTestImpl</em> is a simple/pure Java in-memory implementation
+ * of the interface, for testing.</li>
+ * <li><em>messagePojoImpl</em> is a like messageTestImpl with JSON
+ * serialization and deserialization using the Gson library.</li>
+ * <li><em>messageServerImpl</em> is a protobuf-backed implementation, useful
+ * for a multi-server environment where the efficient serialization of protocol
+ * buffers is an advantage. JSON is also supported.</li>
+ * <li><em>messageClientImpl</em> is an efficent javascript implementation for
+ * use with GWT.</li>
+ * </ul>
+ *
+ * There is no particular reason why PST can only be used to generate Java, for
+ * example, a pure JS rather than GWT implementation of the client JSON message
+ * component could be generated[1].
+ *
+ * PST is implemented using the protocol buffer reflection generated by protoc
+ * alongside the actual Message classes it generates; these are converted into
+ * simple Java model objects with simple accessors suitable for accessing from
+ * stringtemplate.
+ *
+ * The code generated by stringtemplate is then post-processed using a simple
+ * custom code formatter since the output from stringtemplate can be hard to
+ * humanly read (e.g. the indentation is unpredictable).
+ *
+ * [1] although, currently it is hardcoded in PST to generate .java files, and
+ * the model has Java-centric methods.  The code formatter also assumes that
+ * it is run over a Java file.  These all could be easily modified, however.
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class Pst {
+
+  private final File outputDir;
+  private final FileDescriptor fd;
+  private final Styler styler;
+  private final Iterable<File> templates;
+  private final boolean saveBackups;
+  private final boolean useInt52;
+
+  /**
+   * @param outputDir the base directory to write the generated files
+   * @param fd the {@link FileDescriptor} of the protobuf to use (i.e. pass to
+   *        each string template)
+   * @param styler the code styler to post-process generated code with
+   * @param templates the collection of string templates to use
+   * @param saveBackups whether to save intermediate generated files
+   * @param useInt52 whether we use doubles to serialize 64-bit integers
+   */
+  public Pst(File outputDir, FileDescriptor fd, Styler styler, Iterable<File> 
templates,
+      boolean saveBackups, boolean useInt52) {
+    this.outputDir = checkNotNull(outputDir, "outputDir cannot be null");
+    this.fd = checkNotNull(fd, "fd cannot be null");
+    this.styler = checkNotNull(styler, "styler cannot be null");
+    this.templates = checkNotNull(templates, "templates cannot be null");
+    this.saveBackups = saveBackups;
+    this.useInt52 = useInt52;
+  }
+
+  /**
+   * Runs the code generation for all templates.
+   */
+  public void run() throws PstException {
+    List<PstException.TemplateException> exceptions = Lists.newArrayList();
+    for (File template : templates) {
+      try {
+        MessageProperties properties = createProperties(template);
+        String groupName = stripSuffix(".st", template.getName());
+        String templateName = properties.hasTemplateName() ?
+            properties.getTemplateName() : "";
+        StringTemplateGroup group = new StringTemplateGroup(groupName + 
"Group", dir(template));
+        StringTemplate st = group.getInstanceOf(groupName);
+        for (Descriptor messageDescriptor : fd.getMessageTypes()) {
+          Message message = new Message(messageDescriptor, templateName, 
properties);
+          st.reset();
+          st.setAttribute("m", message);
+          write(st, new File(
+              outputDir.getPath() + File.separator +
+              message.getFullJavaType().replace('.', File.separatorChar) + "." 
+
+              (properties.hasFileExtension() ? properties.getFileExtension() : 
"java")));
+        }
+      } catch (Exception e) {
+        exceptions.add(new PstException.TemplateException(template.getPath(), 
e));
+      }
+    }
+    if (!exceptions.isEmpty()) {
+      throw new PstException(exceptions);
+    }
+  }
+
+  /**
+   * @return the path to the directory which contains a file, or just the path
+   *         to the file itself if it's already a directory
+   */
+  private String dir(File f) {
+    return f.isDirectory()
+        ? f.getPath()
+        : (Strings.isNullOrEmpty(f.getParent()) ? "." : f.getParent());
+  }
+
+  private String stripSuffix(String suffix, String s) {
+    return s.endsWith(suffix) ? s.substring(0, s.length() - suffix.length()) : 
s;
+  }
+
+  private void write(StringTemplate st, File output) throws IOException {
+    output.getParentFile().mkdirs();
+    BufferedWriter writer = new BufferedWriter(new FileWriter(output));
+    try {
+      writer.write(st.toString());
+    } finally {
+      try {
+        writer.close();
+      } catch (IOException e) {
+        // If another exception is already propagating, we don't
+        // want to throw a secondary one.
+        // This means that exceptions on close() are ignored,
+        // but what could usefully be done for a close()
+        // exception anyway?
+      }
+    }
+    styler.style(output, saveBackups);
+  }
+
+  private MessageProperties createProperties(File template)
+      throws FileNotFoundException, IOException {
+    File propertiesFile =
+        new File(template.getParentFile().getPath() + File.separator + 
"properties");
+    MessageProperties properties = propertiesFile.exists()
+        ? MessageProperties.createFromFile(propertiesFile) : 
MessageProperties.createEmpty();
+    properties.setUseInt52(useInt52);
+    return properties;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/PstCommandLine.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/PstCommandLine.java 
b/pst/src/main/java/org/apache/wave/pst/PstCommandLine.java
new file mode 100644
index 0000000..b725704
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/PstCommandLine.java
@@ -0,0 +1,151 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+import org.apache.wave.pst.style.PstStyler;
+import org.apache.wave.pst.style.Styler;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * Encapsulates the command line options to protobuf-stringtemplate.
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class PstCommandLine {
+
+  private static final String DEFAULT_OUTPUT_DIR = ".";
+  private static final String DEFAULT_PROTO_PATH = ".";
+  private static final Map<String, Styler> STYLERS = ImmutableMap.<String, 
Styler> builder()
+      .put("none", Styler.EMPTY)
+      .put("pst", new PstStyler())
+      .build();
+
+  private final CommandLine cl;
+
+  public PstCommandLine(String... args) throws ParseException {
+    cl = new DefaultParser().parse(getOptions(), args);
+    checkArgs();
+  }
+
+  private void checkArgs() throws ParseException {
+    if (!hasFile()) {
+      throw new ParseException("Must specify file");
+    }
+    if (cl.getArgList().isEmpty()) {
+      throw new ParseException("Must specify at least one template");
+    }
+  }
+
+  private static Options getOptions() {
+    Options options = new Options();
+    options.addOption("h", "help", false, "Show this help");
+    options.addOption("f", "file", true, "The protobuf specification file to 
use");
+    options.addOption("d", "dir", true, String.format(
+        "The base directory to output generated files to (default: %s)", 
DEFAULT_OUTPUT_DIR));
+    options.addOption("s", "styler", true, "The styler to use, if any 
(default: none). " +
+        "Available options: " + STYLERS.keySet());
+    options.addOption("i", "save_pre_styled", false, "Save the intermediate 
pre-styled files");
+    options.addOption("j", "save_java", false, "Save the protoc-generated Java 
file, if any");
+    options.addOption("I", "proto_path", true, "Extra path to search for proto 
extensions. "
+        + "This needs to be specified if the target file is a .proto file with 
any of the PST-"
+        + "specific extensions, in which case the path should include both PST 
source "
+        + "base and the protoc source base; i.e., 
/PATH/TO/PST/src:/PATH/TO/PROTOC/src");
+    options.addOption("t", "int52", true,
+        "Specifies if pst should store 64-bit integers should be serialized to"
+            + "doubles which will use 52-bit precision. It's useful "
+            + "when data is meant to be serialized/deserialized in JavaScript, 
since it doesn't "
+            + "support 64-bit integers (default: false).");
+    return options;
+  }
+
+  public boolean hasHelp() {
+    return cl.hasOption('h');
+  }
+
+  // NOTE: private because it's always true, checked in checkArgs().
+  private boolean hasFile() {
+    return cl.hasOption('f');
+  }
+
+  public static void printHelp() {
+    new HelpFormatter().printHelp(
+        PstMain.class.getSimpleName() + " [options] templates...", 
getOptions());
+  }
+
+  public File getProtoFile() {
+    return new File(cl.getOptionValue('f'));
+  }
+
+  @SuppressWarnings("unchecked")
+  public Iterable<File> getTemplateFiles() {
+    return Iterables.transform(cl.getArgList(), new Function<String, File>() {
+      @Override public File apply(String filename) {
+        return new File(filename);
+      }
+    });
+  }
+
+  public File getOutputDir() {
+    return new File(cl.hasOption('d') ? cl.getOptionValue('d') : 
DEFAULT_OUTPUT_DIR);
+  }
+
+  public File getProtoPath() {
+    return new File(cl.hasOption('I') ? cl.getOptionValue('I') : 
DEFAULT_PROTO_PATH);
+  }
+
+  public Styler getStyler() {
+    if (cl.hasOption('s')) {
+      String stylerName = cl.getOptionValue('s');
+      if (STYLERS.containsKey(stylerName)) {
+        return STYLERS.get(stylerName);
+      } else {
+        System.err.println("WARNING: unrecognised styler: " + stylerName + ", 
using none");
+        return Styler.EMPTY;
+      }
+    } else {
+      return Styler.EMPTY;
+    }
+  }
+
+  public boolean shouldSavePreStyled() {
+    return cl.hasOption('p');
+  }
+
+  public boolean shouldSaveJava() {
+    return cl.hasOption('j');
+  }
+
+  public boolean shouldUseInt52() {
+    return !cl.hasOption('t') //
+        || (cl.hasOption('t') && "true".equals(cl.getOptionValue('t')));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/PstException.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/PstException.java 
b/pst/src/main/java/org/apache/wave/pst/PstException.java
new file mode 100644
index 0000000..9b17bd7
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/PstException.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * Exception caused by any errors caused in code generation.
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class PstException extends Exception {
+
+  public static final class TemplateException extends Exception {
+    private final String templateName;
+
+    public TemplateException(String templateName, String message, Throwable 
cause) {
+      super(message, cause);
+      this.templateName = templateName;
+    }
+
+    public TemplateException(String templateName, Throwable cause) {
+      super(cause);
+      this.templateName = templateName;
+    }
+
+    /**
+     * @return the name of the template being parsed when the exception 
occurred
+     */
+    public String getTemplateName() {
+      return templateName;
+    }
+  }
+
+  private final ImmutableList<TemplateException> exceptions;
+
+  public PstException(List<TemplateException> exceptions) {
+    super();
+    this.exceptions = ImmutableList.copyOf(exceptions);
+  }
+
+  /**
+   * @return all exceptions caused
+   */
+  public ImmutableList<TemplateException> getTemplateExceptions() {
+    return exceptions;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/PstFileDescriptor.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/PstFileDescriptor.java 
b/pst/src/main/java/org/apache/wave/pst/PstFileDescriptor.java
new file mode 100644
index 0000000..499ebc5
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/PstFileDescriptor.java
@@ -0,0 +1,345 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.io.CharStreams;
+import com.google.common.io.Files;
+import com.google.protobuf.Descriptors.FileDescriptor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A loader for a {@link FileDescriptor}, accepting and handling a proto file
+ * specified as:
+ * <ul>
+ * <li>A path to a .proto file.</li>
+ * <li>A path to a .java (protoc-)compiled proto spec.</li>
+ * <li>A path to a .class (javac-) compiled proto spec.</li>
+ * <li>A proto spec that is already on the classpath.</li>
+ * </ul>
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class PstFileDescriptor {
+
+  private final FileDescriptor descriptor;
+
+  /**
+   * Loads the {@link FileDescriptor} from a path. The path may be a class name
+   * (e.g. foo.Bar), path to a class (e.g. bin/foo/Bar.class), or a path to a
+   * Java source file (e.g. src/foo/Bar.java).
+   *
+   * In each case it is the caller's responsibility to ensure that the 
classpath
+   * of the Java runtime is correct.
+   *
+   * @param path the path to load the proto description from
+   * @param intermediateJavaDir path to save the intermediate protoc-
+   *        generated Java file (if any)
+   * @param protoPath any additional path to pass to the protoc compiler
+   */
+  public static FileDescriptor load(String path, File intermediateJavaDir, 
File protoPath) {
+    return new PstFileDescriptor(path, intermediateJavaDir, protoPath).get();
+  }
+
+  private  PstFileDescriptor(String path, File intermediateJavaDir, File 
protoPath) {
+    Class<?> clazz = null;
+    if (path.endsWith(".class")) {
+      clazz = fromPathToClass(path);
+    } else if (path.endsWith(".java")) {
+      clazz = fromPathToJava(path);
+    } else if (path.endsWith(".proto")) {
+      clazz = fromPathToProto(path, intermediateJavaDir, protoPath);
+    } else {
+      clazz = fromClassName(path);
+    }
+
+    if (clazz == null) {
+      descriptor = null;
+    } else {
+      descriptor = asFileDescriptor(clazz);
+    }
+  }
+
+  private FileDescriptor get() {
+    return descriptor;
+  }
+
+  private Class<?> fromClassName(String className) {
+    try {
+      return Class.forName(className);
+    } catch (ClassNotFoundException e) {
+      return null;
+    }
+  }
+
+  private Class<?> fromPathToClass(String pathToClass) {
+    String currentBaseDir = new File(pathToClass).isAbsolute() ? "" : ".";
+    String currentPath = pathToClass;
+    Class<?> clazz = null;
+    while (clazz == null) {
+      clazz = loadClassAtPath(currentBaseDir, currentPath);
+      if (clazz == null) {
+        int indexOfSep = currentPath.indexOf(File.separatorChar);
+        if (indexOfSep == -1) {
+          break;
+        } else {
+          currentBaseDir += File.separator + currentPath.substring(0, 
indexOfSep);
+          currentPath = currentPath.substring(indexOfSep + 1);
+        }
+      }
+    }
+    return clazz;
+  }
+
+  private Class<?> loadClassAtPath(String baseDir, String path) {
+    try {
+      ClassLoader classLoader = new URLClassLoader(new URL[] {new 
File(baseDir).toURI().toURL()});
+      return classLoader.loadClass(getBinaryName(path));
+    } catch (Throwable t) {
+      return null;
+    }
+  }
+
+  private String getBinaryName(String path) {
+    return path.replace(File.separatorChar, '.').substring(0, path.length() - 
".class".length());
+  }
+
+  private Class<?> fromPathToJava(String pathToJava) {
+    try {
+      File dir = Files.createTempDir();
+      String[] javacCommand = new String[] {
+          "javac", pathToJava, "-d", dir.getAbsolutePath(), "-verbose",
+          "-cp", determineClasspath(pathToJava) + ":" + 
determineSystemClasspath()
+      };
+      Process javac = Runtime.getRuntime().exec(javacCommand);
+      consumeStdOut(javac);
+      List<String> stdErr = readLines(javac.getErrorStream());
+      int exitCode = javac.waitFor();
+      if (exitCode != 0) {
+        // Couldn't compile the file.
+        System.err.printf("ERROR: running \"%s\" failed (%s):",
+            Joiner.on(' ').join(javacCommand), exitCode);
+        for (String line : stdErr) {
+          System.err.println(line);
+        }
+        return null;
+      } else {
+        // Compiled the file!  Now to determine where javac put it.
+        Pattern pattern = Pattern.compile("\\[wrote ([^\\]]*)\\]");
+        String pathToClass = null;
+        for (String line : stdErr) {
+          Matcher lineMatcher = pattern.matcher(line);
+          if (lineMatcher.matches()) {
+            pathToClass = lineMatcher.group(1);
+            // NOTE: don't break, as the correct path is the last one matched.
+          }
+        }
+        if (pathToClass != null) {
+          return fromPathToClass(pathToClass);
+        } else {
+          System.err.println("WARNING: couldn't find javac output from javac " 
+ pathToJava);
+          return null;
+        }
+      }
+    } catch (Exception e) {
+      System.err.println("WARNING: exception while processing " + pathToJava + 
": "
+          + e.getMessage());
+      return null;
+    }
+  }
+
+  /**
+   * Fires off a background thread to consume anything written to a process'
+   * standard output. Without running this, a process that outputs too much 
data
+   * will block.
+   */
+  private void consumeStdOut(Process p) {
+    final InputStream o = p.getInputStream();
+    Thread t = new Thread() {
+      @Override
+      public void run() {
+        try {
+          while (o.read() != -1) {}
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+    };
+    t.setDaemon(true);
+    t.start();
+  }
+
+  private String determineClasspath(String pathToJava) {
+    // Try to determine the classpath component of a path by looking at the
+    // path components.
+    StringBuilder classpath = new StringBuilder();
+    if (new File(pathToJava).isAbsolute()) {
+      classpath.append(File.separator);
+    }
+
+    // This is just silly, but it will get by for now.
+    for (String component : pathToJava.split(File.separator)) {
+      if (component.equals("org")
+          || component.equals("com")
+          || component.equals("au")) {
+        return classpath.toString();
+      } else {
+        classpath.append(component + File.separator);
+      }
+    }
+
+    System.err.println("WARNING: couldn't determine classpath for " + 
pathToJava);
+    return ".";
+  }
+
+  private String determineSystemClasspath() {
+    StringBuilder s = new StringBuilder();
+    boolean needsColon = false;
+    for (URL url : ((URLClassLoader) 
ClassLoader.getSystemClassLoader()).getURLs()) {
+      if (needsColon) {
+        s.append(':');
+      }
+      s.append(url.getPath());
+      needsColon = true;
+    }
+    return s.toString();
+  }
+
+  private Class<?> fromPathToProto(String pathToProto, File 
intermediateJavaDir, File protoPath) {
+    try {
+      intermediateJavaDir.mkdirs();
+      File proto = new File(pathToProto);
+      String[] protocCommand = new String[] {
+          "protoc", tryGetRelativePath(proto),
+          "-I" + protoPath.getPath(),
+          "--java_out", intermediateJavaDir.getAbsolutePath()
+      };
+      Process protoc = Runtime.getRuntime().exec(protocCommand);
+      // TODO(ben): configure timeout?
+      killProcessAfter(10, TimeUnit.SECONDS, protoc);
+      int exitCode = protoc.waitFor();
+      if (exitCode != 0) {
+        // Couldn't compile the file.
+        System.err.printf("ERROR: running \"%s\" failed (%s):",
+            Joiner.on(' ').join(protocCommand), exitCode);
+        for (String line : readLines(protoc.getErrorStream())) {
+          System.err.println(line);
+        }
+        return null;
+      } else {
+        final String javaFileName = capitalize(stripSuffix(".proto", 
proto.getName())) + ".java";
+        String maybeJavaFilePath = find(intermediateJavaDir, new 
Predicate<File>() {
+          @Override public boolean apply(File f) {
+            return f.getName().equals(javaFileName);
+          }
+        });
+        if (maybeJavaFilePath == null) {
+          System.err.println("ERROR: couldn't find result of protoc in " + 
intermediateJavaDir);
+          return null;
+        }
+        return fromPathToJava(maybeJavaFilePath);
+      }
+    } catch (Exception e) {
+      System.err.println("WARNING: exception while processing " + pathToProto 
+ ": "
+          + e.getMessage());
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  private String find(File dir, Predicate<File> predicate) {
+    for (File file : dir.listFiles()) {
+      if (file.isDirectory()) {
+        String path = find(file, predicate);
+        if (path != null) {
+          return path;
+        }
+      }
+      if (predicate.apply(file)) {
+        return file.getAbsolutePath();
+      }
+    }
+    return null;
+  }
+
+  private String tryGetRelativePath(File file) {
+    String pwd = System.getProperty("user.dir");
+    return stripPrefix(pwd + File.separator, file.getAbsolutePath());
+  }
+
+  private String stripPrefix(String prefix, String s) {
+    return s.startsWith(prefix) ? s.substring(prefix.length()) : s;
+  }
+
+  private String stripSuffix(String suffix, String s) {
+    return s.endsWith(suffix) ? s.substring(0, s.length() - suffix.length()) : 
s;
+  }
+
+  private String capitalize(String s) {
+    return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+  }
+
+  private List<String> readLines(InputStream is) {
+    try {
+      return CharStreams.readLines(new InputStreamReader(is));
+    } catch (IOException e) {
+     e.printStackTrace();
+      // TODO(kalman): this is a bit hacky, deal with it properly.
+      return Collections.singletonList("(Error, couldn't read lines from the 
input stream. " +
+          "Try running the command external to PST to view the output.)");
+    }
+  }
+
+  private FileDescriptor asFileDescriptor(Class<?> clazz) {
+    try {
+      Method method = clazz.getMethod("getDescriptor");
+      return (FileDescriptor) method.invoke(null);
+    } catch (Exception e) {
+      return null;
+    }
+  }
+
+  private void killProcessAfter(final long delay, final TimeUnit unit, final 
Process process) {
+    Thread processKiller = new Thread() {
+      @Override public void run() {
+        try {
+          Thread.sleep(unit.toMillis(delay));
+          process.destroy();
+        } catch (InterruptedException e) {
+        }
+      }
+    };
+    processKiller.setDaemon(true);
+    processKiller.start();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/PstMain.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/PstMain.java 
b/pst/src/main/java/org/apache/wave/pst/PstMain.java
new file mode 100644
index 0000000..3faeba1
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/PstMain.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst;
+
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+import com.google.protobuf.Descriptors.FileDescriptor;
+
+import org.apache.commons.cli.ParseException;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Entry point for command line protobuf-stringtemplate.
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class PstMain {
+
+  public static void main(String[] args) {
+    PstCommandLine cl = null;
+    try {
+      cl = new PstCommandLine(args);
+    } catch (ParseException e) {
+      System.err.println("Error parsing command line arguments: " + 
e.getMessage());
+      PstCommandLine.printHelp();
+      System.exit(1);
+    }
+
+    if (cl.hasHelp()) {
+      PstCommandLine.printHelp();
+      System.exit(0);
+    }
+
+    FileDescriptor fd = PstFileDescriptor.load(
+        cl.getProtoFile().getPath(),
+        cl.shouldSaveJava() ? cl.getOutputDir() : Files.createTempDir(),
+        cl.getProtoPath());
+    if (fd == null) {
+      System.err.println("Error: cannot find file descriptor for " + 
cl.getProtoFile());
+      System.exit(1);
+    }
+
+    boolean failed = false;
+
+    List<File> templates = Lists.newArrayList();
+    for (File maybeTemplate : cl.getTemplateFiles()) {
+      if (maybeTemplate.exists()) {
+        templates.add(maybeTemplate);
+      } else {
+        System.err.println("ERROR: template " + maybeTemplate.getPath() + " 
does not exist.");
+        failed = true;
+      }
+    }
+
+    Pst pst = new Pst(cl.getOutputDir(), fd, cl.getStyler(), templates, 
cl.shouldSavePreStyled(),
+        cl.shouldUseInt52());
+    try {
+      pst.run();
+    } catch (PstException e) {
+      System.err.printf("ERROR: generation failed for %d/%d templates:\n",
+          e.getTemplateExceptions().size(), templates.size());
+      for (PstException.TemplateException te : e.getTemplateExceptions()) {
+        System.err.println('\n' + te.getTemplateName() + " failed:");
+        te.printStackTrace(System.err);
+      }
+      failed = true;
+    }
+
+    if (failed) {
+      System.exit(1);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/36445930/pst/src/main/java/org/apache/wave/pst/model/EnumValue.java
----------------------------------------------------------------------
diff --git a/pst/src/main/java/org/apache/wave/pst/model/EnumValue.java 
b/pst/src/main/java/org/apache/wave/pst/model/EnumValue.java
new file mode 100644
index 0000000..f246d13
--- /dev/null
+++ b/pst/src/main/java/org/apache/wave/pst/model/EnumValue.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wave.pst.model;
+
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+
+/**
+ * Wraps a {@link EnumValueDescriptor} with methods suitable for 
stringtemplate.
+ *
+ * @author [email protected] (Benjamin Kalman)
+ */
+public final class EnumValue {
+
+  private final EnumValueDescriptor descriptor;
+
+  public EnumValue(EnumValueDescriptor descriptor) {
+    this.descriptor = descriptor;
+  }
+
+  /**
+   * Gets the name of the enum value, for example:
+   * <ul>
+   * <li>org.waveprotocol.pst.examples.Example1.Person.Gender.MALE = 
"MALE".</li>
+   * </ul>
+   *
+   * @return the name of the enum value
+   */
+  public String getName() {
+    return descriptor.getName();
+  }
+
+  /**
+   * Gets the number of the enum value, for example:
+   * <ul>
+   * <li>org.waveprotocol.pst.examples.Example1.Person.Gender.MALE = 1.</li>
+   * </ul>
+   *
+   * @return the name of the enum value
+   */
+  public int getNumber() {
+    return descriptor.getNumber();
+  }
+}

Reply via email to