avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cutt...@apache.org
Subject svn commit: r894933 - in /hadoop/avro/trunk: ./ src/doc/content/xdocs/ src/java/org/apache/avro/ src/java/org/apache/avro/genavro/ src/java/org/apache/avro/tool/ src/test/genavro/ src/test/genavro/input/ src/test/genavro/output/ src/test/java/org/apach...
Date Thu, 31 Dec 2009 20:23:38 GMT
Author: cutting
Date: Thu Dec 31 20:23:22 2009
New Revision: 894933

URL: http://svn.apache.org/viewvc?rev=894933&view=rev
Log:
AVRO-258.  Add GenAvro language tool.  Contributed by Todd Lipcon.

Added:
    hadoop/avro/trunk/src/doc/content/xdocs/genavro.xml
    hadoop/avro/trunk/src/java/org/apache/avro/genavro/
    hadoop/avro/trunk/src/java/org/apache/avro/genavro/genavro.jj
    hadoop/avro/trunk/src/java/org/apache/avro/tool/GenAvroTool.java
    hadoop/avro/trunk/src/test/genavro/
    hadoop/avro/trunk/src/test/genavro/input/
    hadoop/avro/trunk/src/test/genavro/input/interop.genavro
    hadoop/avro/trunk/src/test/genavro/input/mr_events.genavro
    hadoop/avro/trunk/src/test/genavro/input/namespaces.genavro
    hadoop/avro/trunk/src/test/genavro/input/reservedwords.genavro
    hadoop/avro/trunk/src/test/genavro/input/simple.genavro
    hadoop/avro/trunk/src/test/genavro/input/unicode.genavro
    hadoop/avro/trunk/src/test/genavro/output/
    hadoop/avro/trunk/src/test/genavro/output/interop.avpr
    hadoop/avro/trunk/src/test/genavro/output/mr_events.avpr
    hadoop/avro/trunk/src/test/genavro/output/namespaces.avpr
    hadoop/avro/trunk/src/test/genavro/output/reservedwords.avpr
    hadoop/avro/trunk/src/test/genavro/output/simple.avpr
    hadoop/avro/trunk/src/test/genavro/output/unicode.avpr
    hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/
    hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/TestGenAvro.java
Modified:
    hadoop/avro/trunk/CHANGES.txt
    hadoop/avro/trunk/build.xml
    hadoop/avro/trunk/ivy.xml
    hadoop/avro/trunk/src/doc/content/xdocs/site.xml
    hadoop/avro/trunk/src/java/org/apache/avro/Schema.java
    hadoop/avro/trunk/src/java/org/apache/avro/tool/Main.java

Modified: hadoop/avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Thu Dec 31 20:23:22 2009
@@ -43,6 +43,8 @@
     AVRO-272. Extend RPCContext to include message. 
     (Philip Zeyliger via cutting)
 
+    AVRO-258. Add GenAvro language tool.  (Todd Lipcon via cutting)
+
   IMPROVEMENTS
 
     AVRO-157. Changes from code review comments for C++. (sbanacho)

Modified: hadoop/avro/trunk/build.xml
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/build.xml?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/build.xml (original)
+++ hadoop/avro/trunk/build.xml Thu Dec 31 20:23:22 2009
@@ -59,6 +59,8 @@
   <property name="test.junit.output.format" value="plain"/>
   <property name="test.java.src.dir" value="${basedir}/src/test/java"/>
   <property name="test.schemata.dir" value="${basedir}/src/test/schemata"/>
+  <property name="test.genavro.dir" value="${basedir}/src/test/genavro"/>
+  <property name="test.genavro.mode" value="run" />
   <property name="test.java.build.dir" value="${build.dir}/test"/>
   <property name="test.java.generated.build.dir" value="${test.java.build.dir}/generated"/>
   <property name="test.java.generated.dir" value="${test.java.generated.build.dir}/src"/>
@@ -144,10 +146,25 @@
 
   <target name="compile" depends="compile-java,compile-c,compile-cpp"/>
 
-  <target name="compile-java" depends="schemata,ivy-retrieve">
-    <java-compiler excludes="**/ipc/** **/*Requestor.java **/*Responder.java"/>
+  <target name="javacc" depends="ivy-retrieve">
+    <mkdir dir="${build.dir}/src/org/apache/avro/genavro"/>
+    <symlink link="${ivy.lib}/javacc.jar" resource="${ivy.lib}/javacc-5.0.jar"
+             overwrite="true" />
+    <javacc target="${src.dir}/java/org/apache/avro/genavro/genavro.jj"
+            outputdirectory="${build.dir}/src/org/apache/avro/genavro"
+            javacchome="${ivy.lib}"/>
+  </target>
+
+  <target name="compile-java" depends="javacc,schemata,ivy-retrieve">
+    <java-compiler excludes="**/ipc/** **/*Requestor.java **/*Responder.java" >
+      <src path="${build.dir}/src"/>
+      <src path="${java.src.dir}"/>
+    </java-compiler>
     <java-avro-compiler/>
-    <java-compiler/>
+    <java-compiler>
+      <src path="${build.dir}/src"/>
+      <src path="${java.src.dir}"/>
+    </java-compiler>
   </target>
 
   <target name="ivy-download" unless="ivy.jar.exists" depends="init">
@@ -175,17 +192,16 @@
   </target>
 
   <macrodef name="java-compiler">
-    <attribute name="src" default="${java.src.dir}"/>
     <attribute name="dest" default="${build.classes}"/>
     <attribute name="includes" default="**/*.java"/>
     <attribute name="excludes" default=""/>
     <attribute name="classpath" default="java.classpath"/>
+    <element name="src" implicit="yes"/>
     <sequential>
       <javac 
-	 srcdir="@{src}"
 	 destdir="@{dest}"
-	 includes="@{includes}"
-	 excludes="@{excludes}"
+         includes="@{includes}"
+         excludes="@{excludes}" 
 	 encoding="${javac.encoding}" 
 	 debug="${javac.debug}"
 	 optimize="${javac.optimize}"
@@ -194,6 +210,7 @@
 	 deprecation="${javac.deprecation}">
 	<compilerarg line="${javac.args} ${javac.args.warnings}" />
 	<classpath refid="@{classpath}"/>
+        <src />
       </javac>
     </sequential>
   </macrodef>
@@ -241,9 +258,10 @@
 			generated="${test.java.generated.dir}"
 			dest="${test.java.generated.classes}"
 			classpath="test.java.classpath"/>
-    <java-compiler src="${test.java.src.dir}"
-		   dest="${test.java.classes}"
-		   classpath="test.java.classpath"/>
+    <java-compiler dest="${test.java.classes}"
+		   classpath="test.java.classpath">
+      <src path="${test.java.src.dir}" />
+    </java-compiler>
     <taskdef
        name="paranamer" 
        classname="com.thoughtworks.paranamer.ant.ParanamerGeneratorTask">
@@ -284,8 +302,10 @@
 	</fileset>
       </schema>
 
-      <java-compiler src="@{generated}" dest="@{dest}"
-		     classpath="@{classpath}"/>
+      <java-compiler dest="@{dest}"
+		     classpath="@{classpath}">
+        <src path="@{generated}" />
+      </java-compiler>
     </sequential>
   </macrodef>
 
@@ -321,6 +341,8 @@
         <sysproperty key="test.count" value="${test.count}"/>
         <sysproperty key="test.dir" value="${test.java.build.dir}"/>
         <sysproperty key="test.validate" value="${test.validate}"/>
+        <sysproperty key="test.genavro.dir" value="${test.genavro.dir}" />
+        <sysproperty key="test.genavro.mode" value="${test.genavro.mode}" />
         <classpath refid="test.java.classpath"/>
         <formatter type="${test.junit.output.format}"/>
         <batchtest todir="${test.java.build.dir}" unless="testcase">
@@ -509,7 +531,10 @@
     </py-doc>
   </target>
 
-  <target name="doc" depends="forrest.check,javadoc,pydoc,cdoc,cppdoc" description="Generate forrest-based documentation. To use, specify -Dforrest.home=&lt;base of Apache Forrest installation&gt; on the command line." if="forrest.home">
+  <target name="doc" depends="forrestdoc,javadoc,pydoc,cdoc,cppdoc" description="Generate docs">
+  </target>
+
+  <target name="forrestdoc" depends="forrest.check" description="Generate forrest-based documentation. To use, specify -Dforrest.home=&lt;base of Apache Forrest installation&gt; on the command line." if="forrest.home">
     <echo  file="${build.dir}/avro.ent" append="false">
       &lt;!ENTITY AvroVersion "${version}"&gt;
     </echo>

Modified: hadoop/avro/trunk/ivy.xml
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/ivy.xml?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/ivy.xml (original)
+++ hadoop/avro/trunk/ivy.xml Thu Dec 31 20:23:22 2009
@@ -52,6 +52,8 @@
         conf="eclipse->default">
         <artifact name="ant-eclipse" type="bz2" />
     </dependency>
+    <dependency org="net.java.dev.javacc" name="javacc" rev="5.0" />
+    <dependency org="commons-lang" name="commons-lang" rev="2.4" />
   </dependencies>
 
 </ivy-module>

Added: hadoop/avro/trunk/src/doc/content/xdocs/genavro.xml
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/doc/content/xdocs/genavro.xml?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/doc/content/xdocs/genavro.xml (added)
+++ hadoop/avro/trunk/src/doc/content/xdocs/genavro.xml Thu Dec 31 20:23:22 2009
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd" [
+  <!ENTITY % avro-entities PUBLIC "-//Apache//ENTITIES Avro//EN"
+	   "../../../../build/avro.ent">
+  %avro-entities;
+]>
+<document>
+  <header>
+    <title>Avro &AvroVersion; GenAvro Language Docs</title>
+  </header>
+  <body>
+
+    <section id="preamble">
+      <title>Introduction</title>
+
+      <p>This document defines GenAvro, an experimental higher-level language for authoring Avro schemata.
+      Before reading this document, you should have familiarity with the concepts of schemata and protocols,
+      as well as the various primitive and complex types available in Avro.
+      </p>
+      <p>
+        <strong>N.B.</strong> This feature is considered experimental in the current version of Avro and the language
+        has not been finalized. Although major changes are unlikely, some syntax may change in future
+        versions of Avro.
+      </p>
+    </section>
+
+    <section id="overview">
+      <title>Overview</title>
+      <section id="overview_purpose">
+        <title>Purpose</title>
+        <p>The aim of the GenAvro language is to enable developers to author schemata in a way that
+        feels more similar to common programming languages like Java, C++, or Python. Additionally,
+        the GenAvro language may feel more familiar for those users who have previously used the
+        interface description languages (IDLs) in other frameworks like Thrift, Protocol Buffers, or CORBA.
+        </p>
+      </section>
+      <section id="overview_usage">
+        <title>Usage</title>
+        <p>
+          Each GenAvro file defines a single Avro Protocol, and thus generates as its output a JSON-format
+          Avro Protocol file with extension <code>.avpr</code>.
+        </p>
+        <p>
+          To convert a <code>.genavro</code> file into a <code>.avpr</code> file, it must be processed by the
+          <code>avroj genavro</code> tool. For example:
+        </p>
+        <source>
+$ java -jar avroj-1.3.0.jar genavro src/test/genavro/input/namespaces.genavro /tmp/namespaces.avpr
+$ head /tmp/namespaces.avpr
+{
+  "protocol" : "TestNamespace",
+  "namespace" : "avro.test.protocol",
+        </source>
+        <p>
+          The <code>avroj genavro</code> tool can also process input to and from <em>stdin</em> and <em>stdout</em>.
+          See <code>avroj genavro --help</code> for full usage information.
+        </p>
+      </section>
+    </section> <!-- end overview -->
+
+    <section id="defining_protocol">
+      <title>Defining a Protocol in GenAvro</title>
+
+      <p>A GenAvro file consists of exactly one protocol definition. The minimal protocol is defined
+      by the following code:
+      </p>
+      <source>
+protocol MyProtocol {
+}
+      </source>
+      <p>
+        This is equivalent to (and generates) the following JSON protocol definition:
+      </p>
+  <!--  "namespace" : null, TODO: this is generated but shouldnt be - AVRO-263 -->
+      <source>
+{
+"protocol" : "MyProtocol",
+  "types" : [ ],
+  "messages" : {
+  }
+}
+      </source>
+      <p>
+        The namespace of the protocol may be changed using the <code>@namespace</code> annotation:
+      </p>
+      <source>
+@namespace("mynamespace")
+protocol MyProtocol {
+}
+      </source>
+      <p>
+3        This notation is used throughout GenAvro as a way of specifying properties for the annotated element,
+        as will be described later in this document.
+      </p>
+      <p>
+        Protocols in GenAvro can contain the following items:
+      </p>
+        <ul>
+          <li>Definitions of named schemata, including <em>record</em>s, <em>error</em>s, <em>enum</em>s, and <em>fixed</em>s.</li>
+          <li>Definitions of RPC messages</li>
+        </ul>
+    </section>
+    <section id="format_enums">
+      <title>Defining an Enumeration</title>
+      <p>
+        Enums are defined in GenAvro using a syntax similar to C or Java:
+      </p>
+      <source>
+enum Suit {
+  SPADES, DIAMONDS, CLUBS, HEARTS
+}
+      </source>
+      <p>
+        Note that, unlike the JSON format, anonymous enums cannot be defined.
+      </p>
+    </section>
+    <section id="format_fixed">
+      <title>Defining a Fixed Length Field</title>
+      <p>
+        Fixed fields are defined using the following syntax:
+      </p>
+      <source>
+fixed MD5(16);
+      </source>
+      <p>This example defines a fixed-length type called <code>MD5</code> which contains 16 bytes.</p>
+    </section>
+
+    <section id="format_records">
+      <title>Defining Records and Errors</title>
+      <p>
+        Records are defined in GenAvro using a syntax similar to a <code>struct</code> definition in C:
+      </p>
+      <source>
+record Employee {
+  string name;
+  boolean active;
+  long salary;
+}
+      </source>
+      <p>
+        The above example defines a record with the name &ldquo;Employee&rdquo; with three fields.
+      </p>
+      <p>
+        To define an error, simply use the keyword <code>error</code> instead of <code>record</code>.
+        For example:
+      </p>
+      <source>
+error Kaboom {
+  string explanation;
+  int result_code;
+}
+      </source>
+      <p>
+        Each field in a record or error consists of a type and a name, along with optional property annotations.
+      </p>
+      <p>A type reference in GenAvro must be one of:</p>
+      <ul>
+        <li>A primitive type</li>
+        <li>A named schema defined prior to this usage in the same Protocol</li>
+        <li>A complex type (array, map, or union)</li>
+      </ul>
+
+      <section id="primitive_types">
+        <title>Primitive Types</title>
+        <p>The primitive types supported by GenAvro are the same as those supported by Avro's JSON format.
+        This list includes <code>int</code>, <code>long</code>, <code>string</code>, <code>boolean</code>,
+        <code>float</code>, <code>double</code>, <code>null</code>, and <code>bytes</code>.
+        </p>
+      </section>
+
+      <section id="schema_references">
+        <title>References to Named Schemata</title>
+        <p>If a named schema has already been defined in the same GenAvro file, it may be referenced by name
+        as if it were a primitive type:
+        </p>
+        <source>
+record Card {
+  Suit suit; // refers to the enum Card defined above
+  int number;
+}
+        </source>
+      </section>
+      <section id="complex_types">
+        <title>Complex Types</title>
+
+        <section id="arrays">
+          <title>Arrays</title>
+          <p>
+            Array types are written in a manner that will seem familiar to C++ or Java programmers. An array of
+            any type <code>t</code> is denoted <code>array&lt;t&gt;</code>. For example, an array of strings is
+            denoted <code>array&lt;string&gt;</code>, and a multidimensional array of <code>Foo</code> records
+            would be <code>array&lt;array&lt;Foo&gt;&gt;</code>.
+          </p>
+        </section>
+
+        <section id="maps">
+          <title>Maps</title>
+          <p>Map types are written similarly to array types. An array that contains values of type
+          <code>t</code> is written <code>map&lt;t&gt;</code>. As in the JSON schema format, all
+          maps contain <code>string</code>-type keys.</p>
+        </section>
+
+        <section id="unions">
+          <title>Unions</title>
+          <p>Union types are denoted as <code>union { typeA, typeB, typeC, ... }</code>. For example,
+          this record contains a string field that is optional (unioned with <code>null</code>):
+          </p>
+          <source>
+record RecordWithUnion {
+  union { null, string } optionalString;
+}
+          </source>
+          <p>
+            Note that the same restrictions apply to GenAvro unions as apply to unions defined in the
+            JSON format; namely, a record may not contain multiple elements of the same type.
+          </p>
+        </section> <!-- unions -->
+      </section> <!-- complex types -->
+    </section> <!-- how to define records -->
+    <section id="define_messages">
+      <title>Defining RPC Messages</title>
+      <p>The syntax to define an RPC message within a GenAvro protocol is similar to the syntax for
+      a method declaration within a C header file or a Java interface. To define an RPC message
+      <code>add</code> which takes two arguments named <code>foo</code> and <code>bar</code>,
+      returning an <code>int</code>, simply include the following definition within the protocol:
+      </p>
+      <source>
+int add(int foo, int bar);
+      </source>
+      <p>To define a message with no response, you may use the alias <code>void</code>, equivalent
+      to the Avro <code>null</code> type:
+      </p>
+      <source>
+void logMessage(string message);
+      </source>
+      <p>
+        If you have previously defined an error type within the same protocol, you may declare that
+        a message can throw this error using the syntax:
+      </p>
+      <source>
+void goKaboom() throws Kaboom;
+      </source>
+    </section> <!-- define messages -->
+    <section id="minutiae">
+      <title>Other Language Features</title>
+      <section id="minutiae_comments">
+        <title>Comments</title>
+        <p>All Java-style comments are supported within a GenAvro file. Any text following
+        <code>//</code> on a line is ignored, as is any text between <code>/*</code> and
+        <code>*/</code>, possibly spanning multiple lines.</p>
+      </section>
+      <section id="minutiae_escaping">
+        <title>Escaping Identifiers</title>
+        <p>Occasionally, one will need to use a reserved language keyword as an identifier. In order
+        to do so, backticks (<code>`</code>) may be used to escape the identifier. For example, to define
+        a message with the literal name <em>error</em>, you may write:
+        </p>
+        <source>
+void `error`();
+        </source>
+        <p>This syntax is allowed anywhere an identifier is expected.</p>
+      </section>
+      <section id="minutiae_annotations">
+        <title>Annotations for Ordering and Namespaces</title>
+        <p>
+          Java-style annotations may be used to add additional properties to types throughout
+          GenAvro. For example, to specify the sort order of a field within a record, one may use
+          the <code>@order</code> annotation as follows:
+        </p>
+        <source>
+record MyRecord {
+  @order("ascending")
+  string myAscendingSortField;
+
+  @order("descending")
+  string myDescendingField;
+
+  @order("ignore")
+  string myIgnoredField;
+}
+        </source>
+        <p>Similarly, a <code>@namespace</code> annotation may be used to modify the namespace
+        when defining a named schema. For example:
+        </p>
+        <source>
+@namespace("org.apache.avro.firstNamespace")
+protocol MyProto {
+  @namespace("org.apache.avro.someOtherNamespace")
+  record Foo {}
+
+  record Bar {}
+}
+        </source>
+        <p>
+          will define a protocol in the <code>firstNamespace</code> namespace. The record <code>Foo</code> will be
+          defined in <code>someOtherNamespace</code> and <code>Bar</code> will be defined in <code>firstNamespace</code>
+          as it inherits its default from its container.
+        </p>
+      </section>
+    </section>
+    <section id="example">
+      <title>Complete Example</title>
+      <p>The following is a complete example of a GenAvro file that shows most of the above features:</p>
+      <source>
+/**
+ * An example protocol in GenAvro
+ */
+@namespace("org.apache.avro.test")
+protocol Simple {
+  enum Kind {
+    FOO,
+    BAR, // the bar enum value
+    BAZ
+  }
+
+  fixed MD5(16);
+
+  record TestRecord {
+    @order("ignore")
+    string name;
+
+    @order("descending")
+    Kind kind;
+
+    MD5 hash;
+
+    union { MD5, null} nullableHash;
+
+    array&lt;long&gt; arrayOfLongs;
+  }
+
+  error TestError {
+    string message;
+  }
+
+  string hello(string greeting);
+  TestRecord echo(TestRecord `record`);
+  int add(int arg1, int arg2);
+  bytes echoBytes(bytes data);
+  void `error`() throws TestError;
+}
+      </source>
+      <p>Additional examples may be found in the Avro source tree under the <code>src/test/genavro/input</code> directory.</p>
+    </section>
+  </body>
+</document>

Modified: hadoop/avro/trunk/src/doc/content/xdocs/site.xml
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/doc/content/xdocs/site.xml?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/src/doc/content/xdocs/site.xml (original)
+++ hadoop/avro/trunk/src/doc/content/xdocs/site.xml Thu Dec 31 20:23:22 2009
@@ -42,10 +42,11 @@
   <docs label="Documentation"> 
     <overview   label="Overview"          href="index.html" />
     <spec       label="Specification"     href="spec.html" />
-    <c-api      label="C API"             href="ext:api/c/index" />
-    <cpp-api    label="C++ API"           href="ext:api/cpp/index" />
     <java-api   label="Java API"          href="ext:api/java/index" />
     <py-api     label="Python API"        href="ext:api/py/index" />
+    <c-api      label="C API"             href="ext:api/c/index" />
+    <cpp-api    label="C++ API"           href="ext:api/cpp/index" />
+    <genavro    label="GenAvro language"  href="genavro.html" />
     <wiki       label="Wiki"              href="ext:wiki" />
     <faq        label="FAQ"               href="ext:faq" />
   </docs>

Modified: hadoop/avro/trunk/src/java/org/apache/avro/Schema.java
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/Schema.java?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/Schema.java (original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/Schema.java Thu Dec 31 20:23:22 2009
@@ -732,7 +732,7 @@
     PRIMITIVES.put("null",    Type.NULL);
   }
 
-  static class Names extends LinkedHashMap<Name, Schema> {
+  public static class Names extends LinkedHashMap<Name, Schema> {
     private String space;                         // default namespace
 
     public Names() {}

Added: hadoop/avro/trunk/src/java/org/apache/avro/genavro/genavro.jj
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/genavro/genavro.jj?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/genavro/genavro.jj (added)
+++ hadoop/avro/trunk/src/java/org/apache/avro/genavro/genavro.jj Thu Dec 31 20:23:22 2009
@@ -0,0 +1,1370 @@
+/**
+ * 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.
+ *
+ * Some portions of this file were modeled after the example Java 1.5
+ * parser included with JavaCC. The following license applies to those
+ * portions:
+ *
+ * Copyright (c) 2006, Sun Microsystems, 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 the Sun Microsystems, 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.
+ */
+
+options {
+  JAVA_UNICODE_ESCAPE = true;
+  UNICODE_INPUT = true;
+  ERROR_REPORTING = true;
+  STATIC = false;
+  FORCE_LA_CHECK = true;
+  JDK_VERSION = "1.6";
+}
+
+PARSER_BEGIN(GenAvro)
+
+package org.apache.avro.genavro;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avro.Schema;
+import org.apache.avro.Schema.*;
+import org.apache.avro.Protocol;
+import org.apache.avro.Protocol.*;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+/**
+ * Grammar to parse a higher-level language into an Avro Schema.
+ *
+ * Note: each instance is not thread-safe, but multiple separate
+ * instances are safely independent.
+ */
+public class GenAvro
+{
+   Names names = new Names();
+}
+
+PARSER_END(GenAvro)
+
+/* WHITE SPACE */
+
+SKIP :
+{
+  " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+/* COMMENTS */
+
+MORE :
+{
+  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
+|
+  "/*" : IN_MULTI_LINE_COMMENT
+}
+
+SPECIAL_TOKEN :
+{
+  <SINGLE_LINE_COMMENT: "//" (~["\n", "\r"])* ("\n" | "\r" | "\r\n")?>
+}
+
+<IN_FORMAL_COMMENT>
+SPECIAL_TOKEN :
+{
+  <FORMAL_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_MULTI_LINE_COMMENT>
+SPECIAL_TOKEN :
+{
+  <MULTI_LINE_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
+MORE :
+{
+  < ~[] >
+}
+
+/* RESERVED WORDS AND LITERALS */
+
+TOKEN :
+{
+  < ARRAY: "array" >
+| < BOOLEAN: "boolean" >
+| < DOUBLE: "double" >
+| < ENUM: "enum" >
+| < ERROR: "error" >
+| < FALSE: "false" >
+| < FIXED: "fixed" >
+| < FLOAT: "float" >
+| < INT: "int" >
+| < LONG: "long" >
+| < MAP: "map" >
+| < BYTES: "bytes" >
+| < STRING: "string" >
+| < NULL: "null" >
+| < PROTOCOL: "protocol" >
+| < RECORD: "record" >
+| < THROWS: "throws" >
+| < TRUE: "true" >
+| < UNION: "union" >
+| < VOID: "void" >
+}
+
+/* LITERALS */
+
+TOKEN :
+{
+  < INTEGER_LITERAL:
+        <DECIMAL_LITERAL> (["l","L"])?
+      | <HEX_LITERAL> (["l","L"])?
+      | <OCTAL_LITERAL> (["l","L"])?
+  >
+|
+  < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
+|
+  < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+|
+  < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+|
+  < FLOATING_POINT_LITERAL:
+        <DECIMAL_FLOATING_POINT_LITERAL>
+      | <HEXADECIMAL_FLOATING_POINT_LITERAL>
+  >
+|
+  < #DECIMAL_FLOATING_POINT_LITERAL:
+        (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
+      | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]
+  >
+|
+  < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+|
+  < #HEXADECIMAL_FLOATING_POINT_LITERAL:
+        "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+      | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+  >
+|
+  < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
+|
+  < CHARACTER_LITERAL:
+      "'"
+      (   (~["'","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )
+      "'"
+  >
+|
+  < STRING_LITERAL:
+      "\""
+      (   (~["\"","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )*
+      "\""
+  >
+}
+
+/* IDENTIFIERS */
+
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<PART_LETTER>)* >
+|
+  < #LETTER:
+      [  // all chars for which Character.isIdentifierStart is true
+         "$",
+         "A"-"Z",
+         "_",
+         "a"-"z",
+         "\u00a2"-"\u00a5",
+         "\u00aa",
+         "\u00b5",
+         "\u00ba",
+         "\u00c0"-"\u00d6",
+         "\u00d8"-"\u00f6",
+         "\u00f8"-"\u021f",
+         "\u0222"-"\u0233",
+         "\u0250"-"\u02ad",
+         "\u02b0"-"\u02b8",
+         "\u02bb"-"\u02c1",
+         "\u02d0"-"\u02d1",
+         "\u02e0"-"\u02e4",
+         "\u02ee",
+         "\u037a",
+         "\u0386",
+         "\u0388"-"\u038a",
+         "\u038c",
+         "\u038e"-"\u03a1",
+         "\u03a3"-"\u03ce",
+         "\u03d0"-"\u03d7",
+         "\u03da"-"\u03f3",
+         "\u0400"-"\u0481",
+         "\u048c"-"\u04c4",
+         "\u04c7"-"\u04c8",
+         "\u04cb"-"\u04cc",
+         "\u04d0"-"\u04f5",
+         "\u04f8"-"\u04f9",
+         "\u0531"-"\u0556",
+         "\u0559",
+         "\u0561"-"\u0587",
+         "\u05d0"-"\u05ea",
+         "\u05f0"-"\u05f2",
+         "\u0621"-"\u063a",
+         "\u0640"-"\u064a",
+         "\u0671"-"\u06d3",
+         "\u06d5",
+         "\u06e5"-"\u06e6",
+         "\u06fa"-"\u06fc",
+         "\u0710",
+         "\u0712"-"\u072c",
+         "\u0780"-"\u07a5",
+         "\u0905"-"\u0939",
+         "\u093d",
+         "\u0950",
+         "\u0958"-"\u0961",
+         "\u0985"-"\u098c",
+         "\u098f"-"\u0990",
+         "\u0993"-"\u09a8",
+         "\u09aa"-"\u09b0",
+         "\u09b2",
+         "\u09b6"-"\u09b9",
+         "\u09dc"-"\u09dd",
+         "\u09df"-"\u09e1",
+         "\u09f0"-"\u09f3",
+         "\u0a05"-"\u0a0a",
+         "\u0a0f"-"\u0a10",
+         "\u0a13"-"\u0a28",
+         "\u0a2a"-"\u0a30",
+         "\u0a32"-"\u0a33",
+         "\u0a35"-"\u0a36",
+         "\u0a38"-"\u0a39",
+         "\u0a59"-"\u0a5c",
+         "\u0a5e",
+         "\u0a72"-"\u0a74",
+         "\u0a85"-"\u0a8b",
+         "\u0a8d",
+         "\u0a8f"-"\u0a91",
+         "\u0a93"-"\u0aa8",
+         "\u0aaa"-"\u0ab0",
+         "\u0ab2"-"\u0ab3",
+         "\u0ab5"-"\u0ab9",
+         "\u0abd",
+         "\u0ad0",
+         "\u0ae0",
+         "\u0b05"-"\u0b0c",
+         "\u0b0f"-"\u0b10",
+         "\u0b13"-"\u0b28",
+         "\u0b2a"-"\u0b30",
+         "\u0b32"-"\u0b33",
+         "\u0b36"-"\u0b39",
+         "\u0b3d",
+         "\u0b5c"-"\u0b5d",
+         "\u0b5f"-"\u0b61",
+         "\u0b85"-"\u0b8a",
+         "\u0b8e"-"\u0b90",
+         "\u0b92"-"\u0b95",
+         "\u0b99"-"\u0b9a",
+         "\u0b9c",
+         "\u0b9e"-"\u0b9f",
+         "\u0ba3"-"\u0ba4",
+         "\u0ba8"-"\u0baa",
+         "\u0bae"-"\u0bb5",
+         "\u0bb7"-"\u0bb9",
+         "\u0c05"-"\u0c0c",
+         "\u0c0e"-"\u0c10",
+         "\u0c12"-"\u0c28",
+         "\u0c2a"-"\u0c33",
+         "\u0c35"-"\u0c39",
+         "\u0c60"-"\u0c61",
+         "\u0c85"-"\u0c8c",
+         "\u0c8e"-"\u0c90",
+         "\u0c92"-"\u0ca8",
+         "\u0caa"-"\u0cb3",
+         "\u0cb5"-"\u0cb9",
+         "\u0cde",
+         "\u0ce0"-"\u0ce1",
+         "\u0d05"-"\u0d0c",
+         "\u0d0e"-"\u0d10",
+         "\u0d12"-"\u0d28",
+         "\u0d2a"-"\u0d39",
+         "\u0d60"-"\u0d61",
+         "\u0d85"-"\u0d96",
+         "\u0d9a"-"\u0db1",
+         "\u0db3"-"\u0dbb",
+         "\u0dbd",
+         "\u0dc0"-"\u0dc6",
+         "\u0e01"-"\u0e30",
+         "\u0e32"-"\u0e33",
+         "\u0e3f"-"\u0e46",
+         "\u0e81"-"\u0e82",
+         "\u0e84",
+         "\u0e87"-"\u0e88",
+         "\u0e8a",
+         "\u0e8d",
+         "\u0e94"-"\u0e97",
+         "\u0e99"-"\u0e9f",
+         "\u0ea1"-"\u0ea3",
+         "\u0ea5",
+         "\u0ea7",
+         "\u0eaa"-"\u0eab",
+         "\u0ead"-"\u0eb0",
+         "\u0eb2"-"\u0eb3",
+         "\u0ebd",
+         "\u0ec0"-"\u0ec4",
+         "\u0ec6",
+         "\u0edc"-"\u0edd",
+         "\u0f00",
+         "\u0f40"-"\u0f47",
+         "\u0f49"-"\u0f6a",
+         "\u0f88"-"\u0f8b",
+         "\u1000"-"\u1021",
+         "\u1023"-"\u1027",
+         "\u1029"-"\u102a",
+         "\u1050"-"\u1055",
+         "\u10a0"-"\u10c5",
+         "\u10d0"-"\u10f6",
+         "\u1100"-"\u1159",
+         "\u115f"-"\u11a2",
+         "\u11a8"-"\u11f9",
+         "\u1200"-"\u1206",
+         "\u1208"-"\u1246",
+         "\u1248",
+         "\u124a"-"\u124d",
+         "\u1250"-"\u1256",
+         "\u1258",
+         "\u125a"-"\u125d",
+         "\u1260"-"\u1286",
+         "\u1288",
+         "\u128a"-"\u128d",
+         "\u1290"-"\u12ae",
+         "\u12b0",
+         "\u12b2"-"\u12b5",
+         "\u12b8"-"\u12be",
+         "\u12c0",
+         "\u12c2"-"\u12c5",
+         "\u12c8"-"\u12ce",
+         "\u12d0"-"\u12d6",
+         "\u12d8"-"\u12ee",
+         "\u12f0"-"\u130e",
+         "\u1310",
+         "\u1312"-"\u1315",
+         "\u1318"-"\u131e",
+         "\u1320"-"\u1346",
+         "\u1348"-"\u135a",
+         "\u13a0"-"\u13f4",
+         "\u1401"-"\u166c",
+         "\u166f"-"\u1676",
+         "\u1681"-"\u169a",
+         "\u16a0"-"\u16ea",
+         "\u1780"-"\u17b3",
+         "\u17db",
+         "\u1820"-"\u1877",
+         "\u1880"-"\u18a8",
+         "\u1e00"-"\u1e9b",
+         "\u1ea0"-"\u1ef9",
+         "\u1f00"-"\u1f15",
+         "\u1f18"-"\u1f1d",
+         "\u1f20"-"\u1f45",
+         "\u1f48"-"\u1f4d",
+         "\u1f50"-"\u1f57",
+         "\u1f59",
+         "\u1f5b",
+         "\u1f5d",
+         "\u1f5f"-"\u1f7d",
+         "\u1f80"-"\u1fb4",
+         "\u1fb6"-"\u1fbc",
+         "\u1fbe",
+         "\u1fc2"-"\u1fc4",
+         "\u1fc6"-"\u1fcc",
+         "\u1fd0"-"\u1fd3",
+         "\u1fd6"-"\u1fdb",
+         "\u1fe0"-"\u1fec",
+         "\u1ff2"-"\u1ff4",
+         "\u1ff6"-"\u1ffc",
+         "\u203f"-"\u2040",
+         "\u207f",
+         "\u20a0"-"\u20af",
+         "\u2102",
+         "\u2107",
+         "\u210a"-"\u2113",
+         "\u2115",
+         "\u2119"-"\u211d",
+         "\u2124",
+         "\u2126",
+         "\u2128",
+         "\u212a"-"\u212d",
+         "\u212f"-"\u2131",
+         "\u2133"-"\u2139",
+         "\u2160"-"\u2183",
+         "\u3005"-"\u3007",
+         "\u3021"-"\u3029",
+         "\u3031"-"\u3035",
+         "\u3038"-"\u303a",
+         "\u3041"-"\u3094",
+         "\u309d"-"\u309e",
+         "\u30a1"-"\u30fe",
+         "\u3105"-"\u312c",
+         "\u3131"-"\u318e",
+         "\u31a0"-"\u31b7",
+         "\u3400"-"\u4db5",
+         "\u4e00"-"\u9fa5",
+         "\ua000"-"\ua48c",
+         "\uac00"-"\ud7a3",
+         "\uf900"-"\ufa2d",
+         "\ufb00"-"\ufb06",
+         "\ufb13"-"\ufb17",
+         "\ufb1d",
+         "\ufb1f"-"\ufb28",
+         "\ufb2a"-"\ufb36",
+         "\ufb38"-"\ufb3c",
+         "\ufb3e",
+         "\ufb40"-"\ufb41",
+         "\ufb43"-"\ufb44",
+         "\ufb46"-"\ufbb1",
+         "\ufbd3"-"\ufd3d",
+         "\ufd50"-"\ufd8f",
+         "\ufd92"-"\ufdc7",
+         "\ufdf0"-"\ufdfb",
+         "\ufe33"-"\ufe34",
+         "\ufe4d"-"\ufe4f",
+         "\ufe69",
+         "\ufe70"-"\ufe72",
+         "\ufe74",
+         "\ufe76"-"\ufefc",
+         "\uff04",
+         "\uff21"-"\uff3a",
+         "\uff3f",
+         "\uff41"-"\uff5a",
+         "\uff65"-"\uffbe",
+         "\uffc2"-"\uffc7",
+         "\uffca"-"\uffcf",
+         "\uffd2"-"\uffd7",
+         "\uffda"-"\uffdc",
+         "\uffe0"-"\uffe1",
+         "\uffe5"-"\uffe6"
+      ]
+  >
+|
+  < #PART_LETTER:
+      [  // all chars for which Character.isIdentifierPart is true
+         "\u0000"-"\u0008",
+         "\u000e"-"\u001b",
+         "$",
+         "0"-"9",
+         "A"-"Z",
+         "_",
+         "a"-"z",
+         "\u007f"-"\u009f",
+         "\u00a2"-"\u00a5",
+         "\u00aa",
+         "\u00b5",
+         "\u00ba",
+         "\u00c0"-"\u00d6",
+         "\u00d8"-"\u00f6",
+         "\u00f8"-"\u021f",
+         "\u0222"-"\u0233",
+         "\u0250"-"\u02ad",
+         "\u02b0"-"\u02b8",
+         "\u02bb"-"\u02c1",
+         "\u02d0"-"\u02d1",
+         "\u02e0"-"\u02e4",
+         "\u02ee",
+         "\u0300"-"\u034e",
+         "\u0360"-"\u0362",
+         "\u037a",
+         "\u0386",
+         "\u0388"-"\u038a",
+         "\u038c",
+         "\u038e"-"\u03a1",
+         "\u03a3"-"\u03ce",
+         "\u03d0"-"\u03d7",
+         "\u03da"-"\u03f3",
+         "\u0400"-"\u0481",
+         "\u0483"-"\u0486",
+         "\u048c"-"\u04c4",
+         "\u04c7"-"\u04c8",
+         "\u04cb"-"\u04cc",
+         "\u04d0"-"\u04f5",
+         "\u04f8"-"\u04f9",
+         "\u0531"-"\u0556",
+         "\u0559",
+         "\u0561"-"\u0587",
+         "\u0591"-"\u05a1",
+         "\u05a3"-"\u05b9",
+         "\u05bb"-"\u05bd",
+         "\u05bf",
+         "\u05c1"-"\u05c2",
+         "\u05c4",
+         "\u05d0"-"\u05ea",
+         "\u05f0"-"\u05f2",
+         "\u0621"-"\u063a",
+         "\u0640"-"\u0655",
+         "\u0660"-"\u0669",
+         "\u0670"-"\u06d3",
+         "\u06d5"-"\u06dc",
+         "\u06df"-"\u06e8",
+         "\u06ea"-"\u06ed",
+         "\u06f0"-"\u06fc",
+         "\u070f"-"\u072c",
+         "\u0730"-"\u074a",
+         "\u0780"-"\u07b0",
+         "\u0901"-"\u0903",
+         "\u0905"-"\u0939",
+         "\u093c"-"\u094d",
+         "\u0950"-"\u0954",
+         "\u0958"-"\u0963",
+         "\u0966"-"\u096f",
+         "\u0981"-"\u0983",
+         "\u0985"-"\u098c",
+         "\u098f"-"\u0990",
+         "\u0993"-"\u09a8",
+         "\u09aa"-"\u09b0",
+         "\u09b2",
+         "\u09b6"-"\u09b9",
+         "\u09bc",
+         "\u09be"-"\u09c4",
+         "\u09c7"-"\u09c8",
+         "\u09cb"-"\u09cd",
+         "\u09d7",
+         "\u09dc"-"\u09dd",
+         "\u09df"-"\u09e3",
+         "\u09e6"-"\u09f3",
+         "\u0a02",
+         "\u0a05"-"\u0a0a",
+         "\u0a0f"-"\u0a10",
+         "\u0a13"-"\u0a28",
+         "\u0a2a"-"\u0a30",
+         "\u0a32"-"\u0a33",
+         "\u0a35"-"\u0a36",
+         "\u0a38"-"\u0a39",
+         "\u0a3c",
+         "\u0a3e"-"\u0a42",
+         "\u0a47"-"\u0a48",
+         "\u0a4b"-"\u0a4d",
+         "\u0a59"-"\u0a5c",
+         "\u0a5e",
+         "\u0a66"-"\u0a74",
+         "\u0a81"-"\u0a83",
+         "\u0a85"-"\u0a8b",
+         "\u0a8d",
+         "\u0a8f"-"\u0a91",
+         "\u0a93"-"\u0aa8",
+         "\u0aaa"-"\u0ab0",
+         "\u0ab2"-"\u0ab3",
+         "\u0ab5"-"\u0ab9",
+         "\u0abc"-"\u0ac5",
+         "\u0ac7"-"\u0ac9",
+         "\u0acb"-"\u0acd",
+         "\u0ad0",
+         "\u0ae0",
+         "\u0ae6"-"\u0aef",
+         "\u0b01"-"\u0b03",
+         "\u0b05"-"\u0b0c",
+         "\u0b0f"-"\u0b10",
+         "\u0b13"-"\u0b28",
+         "\u0b2a"-"\u0b30",
+         "\u0b32"-"\u0b33",
+         "\u0b36"-"\u0b39",
+         "\u0b3c"-"\u0b43",
+         "\u0b47"-"\u0b48",
+         "\u0b4b"-"\u0b4d",
+         "\u0b56"-"\u0b57",
+         "\u0b5c"-"\u0b5d",
+         "\u0b5f"-"\u0b61",
+         "\u0b66"-"\u0b6f",
+         "\u0b82"-"\u0b83",
+         "\u0b85"-"\u0b8a",
+         "\u0b8e"-"\u0b90",
+         "\u0b92"-"\u0b95",
+         "\u0b99"-"\u0b9a",
+         "\u0b9c",
+         "\u0b9e"-"\u0b9f",
+         "\u0ba3"-"\u0ba4",
+         "\u0ba8"-"\u0baa",
+         "\u0bae"-"\u0bb5",
+         "\u0bb7"-"\u0bb9",
+         "\u0bbe"-"\u0bc2",
+         "\u0bc6"-"\u0bc8",
+         "\u0bca"-"\u0bcd",
+         "\u0bd7",
+         "\u0be7"-"\u0bef",
+         "\u0c01"-"\u0c03",
+         "\u0c05"-"\u0c0c",
+         "\u0c0e"-"\u0c10",
+         "\u0c12"-"\u0c28",
+         "\u0c2a"-"\u0c33",
+         "\u0c35"-"\u0c39",
+         "\u0c3e"-"\u0c44",
+         "\u0c46"-"\u0c48",
+         "\u0c4a"-"\u0c4d",
+         "\u0c55"-"\u0c56",
+         "\u0c60"-"\u0c61",
+         "\u0c66"-"\u0c6f",
+         "\u0c82"-"\u0c83",
+         "\u0c85"-"\u0c8c",
+         "\u0c8e"-"\u0c90",
+         "\u0c92"-"\u0ca8",
+         "\u0caa"-"\u0cb3",
+         "\u0cb5"-"\u0cb9",
+         "\u0cbe"-"\u0cc4",
+         "\u0cc6"-"\u0cc8",
+         "\u0cca"-"\u0ccd",
+         "\u0cd5"-"\u0cd6",
+         "\u0cde",
+         "\u0ce0"-"\u0ce1",
+         "\u0ce6"-"\u0cef",
+         "\u0d02"-"\u0d03",
+         "\u0d05"-"\u0d0c",
+         "\u0d0e"-"\u0d10",
+         "\u0d12"-"\u0d28",
+         "\u0d2a"-"\u0d39",
+         "\u0d3e"-"\u0d43",
+         "\u0d46"-"\u0d48",
+         "\u0d4a"-"\u0d4d",
+         "\u0d57",
+         "\u0d60"-"\u0d61",
+         "\u0d66"-"\u0d6f",
+         "\u0d82"-"\u0d83",
+         "\u0d85"-"\u0d96",
+         "\u0d9a"-"\u0db1",
+         "\u0db3"-"\u0dbb",
+         "\u0dbd",
+         "\u0dc0"-"\u0dc6",
+         "\u0dca",
+         "\u0dcf"-"\u0dd4",
+         "\u0dd6",
+         "\u0dd8"-"\u0ddf",
+         "\u0df2"-"\u0df3",
+         "\u0e01"-"\u0e3a",
+         "\u0e3f"-"\u0e4e",
+         "\u0e50"-"\u0e59",
+         "\u0e81"-"\u0e82",
+         "\u0e84",
+         "\u0e87"-"\u0e88",
+         "\u0e8a",
+         "\u0e8d",
+         "\u0e94"-"\u0e97",
+         "\u0e99"-"\u0e9f",
+         "\u0ea1"-"\u0ea3",
+         "\u0ea5",
+         "\u0ea7",
+         "\u0eaa"-"\u0eab",
+         "\u0ead"-"\u0eb9",
+         "\u0ebb"-"\u0ebd",
+         "\u0ec0"-"\u0ec4",
+         "\u0ec6",
+         "\u0ec8"-"\u0ecd",
+         "\u0ed0"-"\u0ed9",
+         "\u0edc"-"\u0edd",
+         "\u0f00",
+         "\u0f18"-"\u0f19",
+         "\u0f20"-"\u0f29",
+         "\u0f35",
+         "\u0f37",
+         "\u0f39",
+         "\u0f3e"-"\u0f47",
+         "\u0f49"-"\u0f6a",
+         "\u0f71"-"\u0f84",
+         "\u0f86"-"\u0f8b",
+         "\u0f90"-"\u0f97",
+         "\u0f99"-"\u0fbc",
+         "\u0fc6",
+         "\u1000"-"\u1021",
+         "\u1023"-"\u1027",
+         "\u1029"-"\u102a",
+         "\u102c"-"\u1032",
+         "\u1036"-"\u1039",
+         "\u1040"-"\u1049",
+         "\u1050"-"\u1059",
+         "\u10a0"-"\u10c5",
+         "\u10d0"-"\u10f6",
+         "\u1100"-"\u1159",
+         "\u115f"-"\u11a2",
+         "\u11a8"-"\u11f9",
+         "\u1200"-"\u1206",
+         "\u1208"-"\u1246",
+         "\u1248",
+         "\u124a"-"\u124d",
+         "\u1250"-"\u1256",
+         "\u1258",
+         "\u125a"-"\u125d",
+         "\u1260"-"\u1286",
+         "\u1288",
+         "\u128a"-"\u128d",
+         "\u1290"-"\u12ae",
+         "\u12b0",
+         "\u12b2"-"\u12b5",
+         "\u12b8"-"\u12be",
+         "\u12c0",
+         "\u12c2"-"\u12c5",
+         "\u12c8"-"\u12ce",
+         "\u12d0"-"\u12d6",
+         "\u12d8"-"\u12ee",
+         "\u12f0"-"\u130e",
+         "\u1310",
+         "\u1312"-"\u1315",
+         "\u1318"-"\u131e",
+         "\u1320"-"\u1346",
+         "\u1348"-"\u135a",
+         "\u1369"-"\u1371",
+         "\u13a0"-"\u13f4",
+         "\u1401"-"\u166c",
+         "\u166f"-"\u1676",
+         "\u1681"-"\u169a",
+         "\u16a0"-"\u16ea",
+         "\u1780"-"\u17d3",
+         "\u17db",
+         "\u17e0"-"\u17e9",
+         "\u180b"-"\u180e",
+         "\u1810"-"\u1819",
+         "\u1820"-"\u1877",
+         "\u1880"-"\u18a9",
+         "\u1e00"-"\u1e9b",
+         "\u1ea0"-"\u1ef9",
+         "\u1f00"-"\u1f15",
+         "\u1f18"-"\u1f1d",
+         "\u1f20"-"\u1f45",
+         "\u1f48"-"\u1f4d",
+         "\u1f50"-"\u1f57",
+         "\u1f59",
+         "\u1f5b",
+         "\u1f5d",
+         "\u1f5f"-"\u1f7d",
+         "\u1f80"-"\u1fb4",
+         "\u1fb6"-"\u1fbc",
+         "\u1fbe",
+         "\u1fc2"-"\u1fc4",
+         "\u1fc6"-"\u1fcc",
+         "\u1fd0"-"\u1fd3",
+         "\u1fd6"-"\u1fdb",
+         "\u1fe0"-"\u1fec",
+         "\u1ff2"-"\u1ff4",
+         "\u1ff6"-"\u1ffc",
+         "\u200c"-"\u200f",
+         "\u202a"-"\u202e",
+         "\u203f"-"\u2040",
+         "\u206a"-"\u206f",
+         "\u207f",
+         "\u20a0"-"\u20af",
+         "\u20d0"-"\u20dc",
+         "\u20e1",
+         "\u2102",
+         "\u2107",
+         "\u210a"-"\u2113",
+         "\u2115",
+         "\u2119"-"\u211d",
+         "\u2124",
+         "\u2126",
+         "\u2128",
+         "\u212a"-"\u212d",
+         "\u212f"-"\u2131",
+         "\u2133"-"\u2139",
+         "\u2160"-"\u2183",
+         "\u3005"-"\u3007",
+         "\u3021"-"\u302f",
+         "\u3031"-"\u3035",
+         "\u3038"-"\u303a",
+         "\u3041"-"\u3094",
+         "\u3099"-"\u309a",
+         "\u309d"-"\u309e",
+         "\u30a1"-"\u30fe",
+         "\u3105"-"\u312c",
+         "\u3131"-"\u318e",
+         "\u31a0"-"\u31b7",
+         "\u3400"-"\u4db5",
+         "\u4e00"-"\u9fa5",
+         "\ua000"-"\ua48c",
+         "\uac00"-"\ud7a3",
+         "\uf900"-"\ufa2d",
+         "\ufb00"-"\ufb06",
+         "\ufb13"-"\ufb17",
+         "\ufb1d"-"\ufb28",
+         "\ufb2a"-"\ufb36",
+         "\ufb38"-"\ufb3c",
+         "\ufb3e",
+         "\ufb40"-"\ufb41",
+         "\ufb43"-"\ufb44",
+         "\ufb46"-"\ufbb1",
+         "\ufbd3"-"\ufd3d",
+         "\ufd50"-"\ufd8f",
+         "\ufd92"-"\ufdc7",
+         "\ufdf0"-"\ufdfb",
+         "\ufe20"-"\ufe23",
+         "\ufe33"-"\ufe34",
+         "\ufe4d"-"\ufe4f",
+         "\ufe69",
+         "\ufe70"-"\ufe72",
+         "\ufe74",
+         "\ufe76"-"\ufefc",
+         "\ufeff",
+         "\uff04",
+         "\uff10"-"\uff19",
+         "\uff21"-"\uff3a",
+         "\uff3f",
+         "\uff41"-"\uff5a",
+         "\uff65"-"\uffbe",
+         "\uffc2"-"\uffc7",
+         "\uffca"-"\uffcf",
+         "\uffd2"-"\uffd7",
+         "\uffda"-"\uffdc",
+         "\uffe0"-"\uffe1",
+         "\uffe5"-"\uffe6",
+         "\ufff9"-"\ufffb"
+      ]
+  >
+}
+
+/* SEPARATORS */
+
+TOKEN :
+{
+  < LPAREN: "(" >
+| < RPAREN: ")" >
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+| < SEMICOLON: ";" >
+| < COMMA: "," >
+| < AT: "@" >
+| < DOT: "." >
+}
+
+TOKEN :
+{
+  < LT: "<" >
+| < GT: ">" >
+| < TICK: "`" >
+}
+
+
+/********************************************
+ * THE GENAVRO LANGUAGE GRAMMAR STARTS HERE *
+ ********************************************/
+
+/**
+ * The input to genavro is a CompilationUnit, which is currently
+ * just a single Protocol.
+ */
+Protocol CompilationUnit():
+{
+  Protocol p;
+}
+{
+  p = ProtocolDeclaration()
+  ( < "\u001a" > )?
+  ( <STUFF_TO_IGNORE: ~[]> )?
+  <EOF>
+  { return p; }
+}
+
+/*
+ * Declaration syntax follows.
+ */
+Schema NamedSchemaDeclaration():
+{
+  Schema s;
+  Map<String, String> props = new HashMap<String, String>();
+  String savedSpace = names.space();
+}
+{
+  ( SchemaProperty(props) )*
+  {
+    if (props.containsKey("namespace")) {
+      names.space(props.get("namespace"));
+    }
+  }
+ (
+     s = FixedDeclaration()
+   | s = EnumDeclaration()
+   | s = RecordDeclaration()
+ )
+ {
+   names.space(savedSpace);
+   return s;
+ }
+}
+
+Schema UnionDefinition():
+{
+  Schema s;
+  List<Schema> schemata = new ArrayList<Schema>();
+}
+{
+ // TODO should probably disallow other unions here in the parser?
+
+  "union"
+  "{"
+  s = Type()
+  { schemata.add(s); }
+
+  (
+    ","
+    s = Type()
+    { schemata.add(s); }
+  )*
+  "}"
+  {
+    return Schema.createUnion(schemata);
+  }
+}
+
+
+Protocol ProtocolDeclaration():
+{
+  String name;
+  Protocol p;
+  Map<String, String> props = new HashMap<String, String>();
+}
+{
+  ( SchemaProperty(props) )*
+  {
+    if (props.containsKey("namespace")) {
+      names.space(props.get("namespace"));
+    }
+  }
+ "protocol"
+   name = Identifier()
+ {
+   p = new Protocol(name, names.space());
+ }
+ ProtocolBody(p)
+ {
+   return p;
+ }
+}
+
+
+Schema EnumDeclaration():
+{
+  String name;
+  List<String> symbols;
+}
+{
+  "enum"
+  name = Identifier()
+  symbols = EnumBody()
+  {
+    Schema s = Schema.createEnum(name, names.space(), symbols);
+    names.add(s);
+    return s;
+  }
+}
+
+List<String> EnumBody():
+{
+  List<String> symbols = new ArrayList<String>();
+}
+{
+  "{"
+  [ EnumConstant(symbols) ( LOOKAHEAD(2) "," EnumConstant(symbols) )* ]
+  "}"
+  {
+    return symbols;
+  }
+}
+
+void EnumConstant(List<String> symbols):
+{
+  String sym;
+}
+{
+  sym = Identifier() { symbols.add(sym); }
+}
+
+void ProtocolBody(Protocol p):
+{
+  Schema schema;
+  Message message;
+  List<Schema> schemata = new ArrayList<Schema>();
+}
+{
+  "{"
+  (
+      schema = NamedSchemaDeclaration()
+      {
+        schemata.add(schema);
+      }
+
+    | message = MessageDeclaration(p)
+      {
+        // TODO this is kind of sketch!!
+        p.getMessages().put(message.getName(), message);
+      }
+  ) *
+  "}"
+
+  {
+    p.setTypes(schemata);
+  }
+}
+
+
+Schema FixedDeclaration():
+{
+  String name;
+  Token sizeTok;
+}
+{
+  "fixed" name = Identifier() "(" sizeTok = <INTEGER_LITERAL> ")"
+  ";"
+  {
+    Schema s = Schema.createFixed(name, names.space(),
+                                  Integer.parseInt(sizeTok.image));
+    names.add(s);
+    return s;
+  }
+}
+
+Schema RecordDeclaration():
+{
+  String name;
+  LinkedHashMap<String, Field> fields = new LinkedHashMap<String, Field>();
+  boolean isError;
+}
+{
+  (
+    "record" { isError = false; }
+    | "error" { isError = true; }
+  )
+  name = Identifier()
+  {
+    Schema result = Schema.createRecord(
+      name, names.space(), isError);
+    names.add(result);
+  }
+  "{"
+    ( FieldDeclaration(fields) )*
+  "}"
+  {
+    result.setFields(fields);
+    return result;
+  }
+}
+
+void SchemaProperty(Map<String, String> properties):
+{
+  String key;
+  String val;
+}
+{
+  "@" key = Identifier() "(" val = Literal() ")"
+  {
+    if (properties.containsKey(key)) {
+      throw new ParseException("Property '" + key + "' already specified " +
+                               " at line " + token.beginLine + ", column " +
+                               token.beginColumn);
+    }
+    properties.put(key, val);
+  }
+}
+
+
+void FieldDeclaration(LinkedHashMap<String, Field> fields):
+{
+  Schema type;
+  Map<String, String> props = new HashMap<String, String>();
+}
+{
+  // TODO should we be able to specify properties on any Type?
+  // or just on field declarations as done here
+
+  ( SchemaProperty(props) )*
+  type = Type()
+  VariableDeclarator(type, fields) ( "," VariableDeclarator(type, fields) )*
+  ";"
+  {
+    for (Map.Entry<String, String> propEntry : props.entrySet()) {
+      type.setProp(propEntry.getKey(), propEntry.getValue());
+    }
+  }
+}
+
+void VariableDeclarator(Schema type, LinkedHashMap<String, Field> fields):
+{
+  String name;
+}
+{
+  name = Identifier()
+  {
+    fields.put(name, new Field(type, null));
+  }
+}
+
+
+Message MessageDeclaration(Protocol p):
+{
+  String name;
+  Schema request;
+  Schema response;
+  List<Schema> errorSchemata = new ArrayList<Schema>();
+  errorSchemata.add(Protocol.SYSTEM_ERROR);
+}
+{
+  response = ResultType()
+  name = Identifier()
+  request = FormalParameters()
+  [ "throws" ErrorList(errorSchemata) ]
+  ";"
+  {
+    Schema errors = Schema.createUnion(errorSchemata);
+    return p.createMessage(name, request, response, errors);
+  }
+}
+
+void ErrorList(List<Schema> errors):
+{
+  Schema s;
+}
+{
+  s = ReferenceType() { errors.add(s); }
+  ( "," s = ReferenceType() { errors.add(s); } )*
+}
+
+Schema FormalParameters():
+{
+  LinkedHashMap<String, Field> fields = new LinkedHashMap<String, Field>();
+}
+{
+  (
+    "(" [ FormalParameter(fields) ( "," FormalParameter(fields) )* ] ")"
+  )
+  {
+    return Schema.createRecord(fields);
+  }
+}
+
+void FormalParameter(LinkedHashMap<String, Field> fields):
+{
+  Schema type;
+}
+{
+  type = Type()
+  VariableDeclarator(type, fields)
+}
+
+Schema Type():
+{
+  Schema s;
+}
+{
+  (
+      LOOKAHEAD(2) s = ReferenceType()
+    | s = PrimitiveType()
+    | s = UnionDefinition()
+    | s = ArrayType()
+    | s = MapType()
+  )
+  {
+    return s;
+  }
+}
+
+Schema ArrayType():
+{
+  Schema elemSchema;
+}
+{
+  "array" "<" elemSchema = Type() ">"
+  {
+    return Schema.createArray(elemSchema);
+  }
+}
+
+Schema MapType():
+{
+  Schema elemSchema;
+}
+{
+  "map" "<" elemSchema = Type() ">"
+  {
+    return Schema.createMap(elemSchema);
+  }
+}
+
+/**
+ * A reference to some other existing type
+ */
+Schema ReferenceType():
+{
+  String part;
+  Token tok;
+  StringBuilder sb = new StringBuilder();
+}
+{
+  (
+    part = Identifier() { sb.append(part); }
+    ("." tok = AnyIdentifier() { sb.append(".").append(tok.image); })*
+    )
+  {
+    Schema type = names.get(sb.toString());
+    if (type == null) {
+      throw new ParseException("Undefined name '" + sb + "'" +
+                               " at line " + token.beginLine + ", column " +
+                               token.beginColumn);
+    }
+    return type;
+  }
+}
+
+Schema PrimitiveType():
+{}
+{
+  "boolean" { return Schema.create(Type.BOOLEAN); }
+| "bytes" { return Schema.create(Type.BYTES); }
+| "int" { return Schema.create(Type.INT); }
+| "string" { return Schema.create(Type.STRING); }
+| "float" { return Schema.create(Type.FLOAT); }
+| "double" { return Schema.create(Type.DOUBLE); }
+| "long" { return Schema.create(Type.LONG); }
+| "null" { return Schema.create(Type.NULL); }
+}
+
+/**
+ * Result types are like other types, except we provide "void" as
+ * an alias of "null"
+ */
+Schema ResultType():
+{
+  Schema schema;
+}
+{
+  LOOKAHEAD(2)
+    "void"          { return Schema.create(Type.NULL); }
+  | schema = Type() { return schema; }
+}
+
+
+String Literal():
+{ Token t; }
+{
+  (
+    t = <INTEGER_LITERAL>
+  | t = <FLOATING_POINT_LITERAL>
+  | t = <CHARACTER_LITERAL>
+  | t = BooleanLiteral()
+  | t = NullLiteral()
+  )
+  {
+    return t.image;
+  }
+| t = <STRING_LITERAL>
+  {
+    String betweenQuotes = t.image.substring(1, t.image.length() - 1);
+    return StringEscapeUtils.unescapeJavaScript(betweenQuotes);
+  }
+}
+
+Token BooleanLiteral():
+{ Token t; }
+{
+  (   t = "true"
+    | t = "false"
+  )
+  {
+    return t;
+  }
+}
+
+Token NullLiteral():
+{
+  Token t;
+}
+{
+  t = "null" { return t; }
+}
+
+String Identifier():
+{
+  Token t;
+}
+{
+  ( t = <IDENTIFIER> { return t.image; } )
+| ( "`" t = AnyIdentifier() "`" {
+    return t.image;
+  })
+}
+
+Token AnyIdentifier():
+{
+  Token t;
+}
+{
+  (t = <ARRAY> |
+   t = <BOOLEAN> |
+   t = <DOUBLE> |
+   t = <ENUM> |
+   t = <ERROR> |
+   t = <FALSE> |
+   t = <FIXED> |
+   t = <FLOAT> |
+   t = <INT> |
+   t = <LONG> |
+   t = <MAP> |
+   t = <BYTES> |
+   t = <STRING> |
+   t = <PROTOCOL> |
+   t = <RECORD> |
+   t = <THROWS> |
+   t = <TRUE> |
+   t = <UNION> |
+   t = <VOID> |
+   t = <IDENTIFIER>)
+  {
+    return t;
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/java/org/apache/avro/tool/GenAvroTool.java
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/tool/GenAvroTool.java?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/tool/GenAvroTool.java (added)
+++ hadoop/avro/trunk/src/java/org/apache/avro/tool/GenAvroTool.java Thu Dec 31 20:23:22 2009
@@ -0,0 +1,78 @@
+/**
+ * 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.avro.tool;
+
+import org.apache.avro.Protocol;
+import org.apache.avro.genavro.GenAvro;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+/**
+ * Avroj Tool implementation for generating Avro JSON schemata from
+ * genavro format files.
+ */
+public class GenAvroTool implements Tool {
+  @Override
+  public int run(InputStream in, PrintStream out, PrintStream err,
+                  List<String> args) throws Exception {
+
+    InputStream parseIn = in;
+    PrintStream parseOut = out;
+
+    if (args.size() > 2 ||
+        (args.size() == 1 && (args.get(0).equals("--help") ||
+                              args.get(0).equals("-help")))) {
+      err.println("Usage: GenAvroTool [in] [out]");
+      err.println("");
+      err.println("If an output path is not specified, outputs to stdout.");
+      err.println("If no input or output is specified, takes input from");
+      err.println("stdin and outputs to stdin.");
+      err.println("The special path \"-\" may also be specified to refer to");
+      err.println("stdin and stdout.");
+      return -1;
+    }
+
+    if (args.size() >= 1 && ! "-".equals(args.get(0))) {
+      parseIn = new FileInputStream(args.get(0));
+    }
+    if (args.size() == 2 && ! "-".equals(args.get(1))) {
+      parseOut = new PrintStream(new FileOutputStream(args.get(1)));
+    }
+
+
+    GenAvro parser = new GenAvro(parseIn);
+    Protocol p = parser.CompilationUnit();
+    parseOut.print(p.toString(true));
+    return 0;
+  }
+
+  @Override
+  public String getName() {
+    return "genavro";
+  }
+
+  @Override
+  public String getShortDescription() {
+    return "Generates a JSON schema from a GenAvro file";
+  }
+}

Modified: hadoop/avro/trunk/src/java/org/apache/avro/tool/Main.java
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/tool/Main.java?rev=894933&r1=894932&r2=894933&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/tool/Main.java (original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/tool/Main.java Thu Dec 31 20:23:22 2009
@@ -43,6 +43,7 @@
         new DataFileReadTool(),
         new DataFileWriteTool(),
         new DataFileGetSchemaTool(),
+        new GenAvroTool()
         }) {
       Tool prev = tools.put(tool.getName(), tool);
       if (prev != null) {

Added: hadoop/avro/trunk/src/test/genavro/input/interop.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/interop.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/interop.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/interop.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+
+// Currently genavro only does Protocols.
+@namespace("org.apache.avro")
+protocol InteropProtocol {
+  record Foo {
+    string label;
+  }
+
+  enum Kind { A, B, C }
+  fixed MD5(16);
+
+  record Node {
+    string label;
+    array<Node> children;
+  }
+
+  record Interop {
+    int intField;
+    long longField;
+    string stringField;
+    boolean boolField;
+    float floatField;
+    double doubleField;
+    null nullField;
+    array<double> arrayField;
+    map<Foo> mapField;
+    union { boolean, double, array<bytes> } unionFIeld;
+    Kind enumField;
+    MD5 fixedField;
+    Node recordField;
+  }
+
+}

Added: hadoop/avro/trunk/src/test/genavro/input/mr_events.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/mr_events.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/mr_events.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/mr_events.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,72 @@
+/**
+ * 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.
+ */
+
+/**
+ * Genavro format for a particular protocol found in Hadoop MapReduce.
+ * Used as a test case/example to show that we can express real-world stuff more
+ * succinctly.
+ */
+@namespace("org.apache.hadoop.mapreduce.jobhistory")
+protocol Events {
+  record JhCounter {
+    string name;
+    string displayName;
+    long value;
+  }
+
+  record JhCounterGroup {
+    string name;
+    string displayName;
+    array<JhCounter> counts;
+  }
+
+  record JhCounters {
+    string name;
+    array<JhCounterGroup> groups;
+  }
+
+  record JobFinished {
+    string jobid;
+    long finishTime;
+    int finishedMaps;
+    int finishedReduces;
+    int failedMaps;
+    int failedReduces;
+    JhCounters totalCounters;
+    JhCounters mapCounters;
+    JhCounters reduceCounters;
+  }
+
+  record JobInited {
+    string jobid;
+    long launchTime;
+    int totalMaps;
+    int totalReduces;
+    string jobStatus;
+  }
+
+  record JobSubmitted {
+    string jobid;
+    string jobName;
+    string userName;
+    long submitTime;
+    string jobConfPath;
+  }
+
+  // ... TODO continue
+}

Added: hadoop/avro/trunk/src/test/genavro/input/namespaces.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/namespaces.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/namespaces.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/namespaces.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+@namespace("avro.test.protocol")
+protocol TestNamespace {
+  @namespace("avro.test.fixed")
+  fixed FixedInOtherNamespace(16);
+
+  fixed FixedInThisNamespace(16);
+
+  @namespace("avro.test.record")
+  record RecordInOtherNamespace {}
+
+  @namespace("avro.test.error")
+  error ErrorInOtherNamespace {}
+
+  @namespace("avro.test.enum")
+  enum EnumInOtherNamespace { FOO }
+
+  record RefersToOthers {
+    avro.test.fixed.FixedInOtherNamespace someFixed;
+    avro.test.record.RecordInOtherNamespace someRecord;
+    avro.test.error.ErrorInOtherNamespace someError;
+    avro.test.enum.EnumInOtherNamespace someEnum;
+    FixedInThisNamespace thisFixed;
+  }
+}

Added: hadoop/avro/trunk/src/test/genavro/input/reservedwords.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/reservedwords.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/reservedwords.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/reservedwords.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+protocol Foo {
+  void `error`();
+  void `void`();
+}

Added: hadoop/avro/trunk/src/test/genavro/input/simple.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/simple.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/simple.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/simple.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,53 @@
+/**
+ * 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.
+ */
+
+/**
+ * A simple test case.
+ */
+@namespace("org.apache.avro.test")
+protocol Simple {
+  enum Kind {
+    FOO,
+    BAR, // the bar enum value
+    BAZ
+  }
+
+  fixed MD5(16);
+
+  record TestRecord {
+    @order("ignore")
+    string name;
+
+    @order("descending")
+    Kind kind;
+
+    MD5 hash;
+
+    union { MD5, null} nullableHash;
+  }
+
+  error TestError {
+    string message;
+  }
+
+  string hello(string greeting);
+  TestRecord echo(TestRecord `record`);
+  int add(int arg1, int arg2);
+  bytes echoBytes(bytes data);
+  void `error`() throws TestError;
+}

Added: hadoop/avro/trunk/src/test/genavro/input/unicode.genavro
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/input/unicode.genavro?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/input/unicode.genavro (added)
+++ hadoop/avro/trunk/src/test/genavro/input/unicode.genavro Thu Dec 31 20:23:22 2009
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+/**
+* This is a test that UTF8 functions correctly.
+* このテストでは、UTF - 8で正しく機能している。
+* 这是一个测试,UTF - 8的正常运行。
+*/
+protocol Протоколы {
+  record Структура {
+    string Строковый;
+    string 文字列;
+  }
+}

Added: hadoop/avro/trunk/src/test/genavro/output/interop.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/interop.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/interop.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/interop.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,87 @@
+{
+  "protocol" : "InteropProtocol",
+  "namespace" : "org.apache.avro",
+  "types" : [ {
+    "type" : "record",
+    "name" : "Foo",
+    "fields" : [ {
+      "name" : "label",
+      "type" : "string"
+    } ]
+  }, {
+    "type" : "enum",
+    "name" : "Kind",
+    "symbols" : [ "A", "B", "C" ]
+  }, {
+    "type" : "fixed",
+    "name" : "MD5",
+    "size" : 16
+  }, {
+    "type" : "record",
+    "name" : "Node",
+    "fields" : [ {
+      "name" : "label",
+      "type" : "string"
+    }, {
+      "name" : "children",
+      "type" : {
+        "type" : "array",
+        "items" : "Node"
+      }
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "Interop",
+    "fields" : [ {
+      "name" : "intField",
+      "type" : "int"
+    }, {
+      "name" : "longField",
+      "type" : "long"
+    }, {
+      "name" : "stringField",
+      "type" : "string"
+    }, {
+      "name" : "boolField",
+      "type" : "boolean"
+    }, {
+      "name" : "floatField",
+      "type" : "float"
+    }, {
+      "name" : "doubleField",
+      "type" : "double"
+    }, {
+      "name" : "nullField",
+      "type" : "null"
+    }, {
+      "name" : "arrayField",
+      "type" : {
+        "type" : "array",
+        "items" : "double"
+      }
+    }, {
+      "name" : "mapField",
+      "type" : {
+        "type" : "map",
+        "values" : "Foo"
+      }
+    }, {
+      "name" : "unionFIeld",
+      "type" : [ "boolean", "double", {
+        "type" : "array",
+        "items" : "bytes"
+      } ]
+    }, {
+      "name" : "enumField",
+      "type" : "Kind"
+    }, {
+      "name" : "fixedField",
+      "type" : "MD5"
+    }, {
+      "name" : "recordField",
+      "type" : "Node"
+    } ]
+  } ],
+  "messages" : {
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/genavro/output/mr_events.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/mr_events.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/mr_events.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/mr_events.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,118 @@
+{
+  "protocol" : "Events",
+  "namespace" : "org.apache.hadoop.mapreduce.jobhistory",
+  "types" : [ {
+    "type" : "record",
+    "name" : "JhCounter",
+    "fields" : [ {
+      "name" : "name",
+      "type" : "string"
+    }, {
+      "name" : "displayName",
+      "type" : "string"
+    }, {
+      "name" : "value",
+      "type" : "long"
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "JhCounterGroup",
+    "fields" : [ {
+      "name" : "name",
+      "type" : "string"
+    }, {
+      "name" : "displayName",
+      "type" : "string"
+    }, {
+      "name" : "counts",
+      "type" : {
+        "type" : "array",
+        "items" : "JhCounter"
+      }
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "JhCounters",
+    "fields" : [ {
+      "name" : "name",
+      "type" : "string"
+    }, {
+      "name" : "groups",
+      "type" : {
+        "type" : "array",
+        "items" : "JhCounterGroup"
+      }
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "JobFinished",
+    "fields" : [ {
+      "name" : "jobid",
+      "type" : "string"
+    }, {
+      "name" : "finishTime",
+      "type" : "long"
+    }, {
+      "name" : "finishedMaps",
+      "type" : "int"
+    }, {
+      "name" : "finishedReduces",
+      "type" : "int"
+    }, {
+      "name" : "failedMaps",
+      "type" : "int"
+    }, {
+      "name" : "failedReduces",
+      "type" : "int"
+    }, {
+      "name" : "totalCounters",
+      "type" : "JhCounters"
+    }, {
+      "name" : "mapCounters",
+      "type" : "JhCounters"
+    }, {
+      "name" : "reduceCounters",
+      "type" : "JhCounters"
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "JobInited",
+    "fields" : [ {
+      "name" : "jobid",
+      "type" : "string"
+    }, {
+      "name" : "launchTime",
+      "type" : "long"
+    }, {
+      "name" : "totalMaps",
+      "type" : "int"
+    }, {
+      "name" : "totalReduces",
+      "type" : "int"
+    }, {
+      "name" : "jobStatus",
+      "type" : "string"
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "JobSubmitted",
+    "fields" : [ {
+      "name" : "jobid",
+      "type" : "string"
+    }, {
+      "name" : "jobName",
+      "type" : "string"
+    }, {
+      "name" : "userName",
+      "type" : "string"
+    }, {
+      "name" : "submitTime",
+      "type" : "long"
+    }, {
+      "name" : "jobConfPath",
+      "type" : "string"
+    } ]
+  } ],
+  "messages" : {
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/genavro/output/namespaces.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/namespaces.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/namespaces.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/namespaces.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,50 @@
+{
+  "protocol" : "TestNamespace",
+  "namespace" : "avro.test.protocol",
+  "types" : [ {
+    "type" : "fixed",
+    "name" : "FixedInOtherNamespace",
+    "namespace" : "avro.test.fixed",
+    "size" : 16
+  }, {
+    "type" : "fixed",
+    "name" : "FixedInThisNamespace",
+    "size" : 16
+  }, {
+    "type" : "record",
+    "name" : "RecordInOtherNamespace",
+    "namespace" : "avro.test.record",
+    "fields" : [ ]
+  }, {
+    "type" : "error",
+    "name" : "ErrorInOtherNamespace",
+    "namespace" : "avro.test.error",
+    "fields" : [ ]
+  }, {
+    "type" : "enum",
+    "name" : "EnumInOtherNamespace",
+    "namespace" : "avro.test.enum",
+    "symbols" : [ "FOO" ]
+  }, {
+    "type" : "record",
+    "name" : "RefersToOthers",
+    "fields" : [ {
+      "name" : "someFixed",
+      "type" : "avro.test.fixed.FixedInOtherNamespace"
+    }, {
+      "name" : "someRecord",
+      "type" : "avro.test.record.RecordInOtherNamespace"
+    }, {
+      "name" : "someError",
+      "type" : "avro.test.error.ErrorInOtherNamespace"
+    }, {
+      "name" : "someEnum",
+      "type" : "avro.test.enum.EnumInOtherNamespace"
+    }, {
+      "name" : "thisFixed",
+      "type" : "FixedInThisNamespace"
+    } ]
+  } ],
+  "messages" : {
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/genavro/output/reservedwords.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/reservedwords.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/reservedwords.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/reservedwords.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,15 @@
+{
+  "protocol" : "Foo",
+  "namespace" : null,
+  "types" : [ ],
+  "messages" : {
+    "error" : {
+      "request" : [ ],
+      "response" : "null"
+    },
+    "void" : {
+      "request" : [ ],
+      "response" : "null"
+    }
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/genavro/output/simple.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/simple.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/simple.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/simple.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,78 @@
+{
+  "protocol" : "Simple",
+  "namespace" : "org.apache.avro.test",
+  "types" : [ {
+    "type" : "enum",
+    "name" : "Kind",
+    "symbols" : [ "FOO", "BAR", "BAZ" ],
+    "order" : "descending"
+  }, {
+    "type" : "fixed",
+    "name" : "MD5",
+    "size" : 16
+  }, {
+    "type" : "record",
+    "name" : "TestRecord",
+    "fields" : [ {
+      "name" : "name",
+      "type" : {
+        "type" : "string",
+        "order" : "ignore"
+      }
+    }, {
+      "name" : "kind",
+      "type" : "Kind"
+    }, {
+      "name" : "hash",
+      "type" : "MD5"
+    }, {
+      "name" : "nullableHash",
+      "type" : [ "MD5", "null" ]
+    } ]
+  }, {
+    "type" : "error",
+    "name" : "TestError",
+    "fields" : [ {
+      "name" : "message",
+      "type" : "string"
+    } ]
+  } ],
+  "messages" : {
+    "hello" : {
+      "request" : [ {
+        "name" : "greeting",
+        "type" : "string"
+      } ],
+      "response" : "string"
+    },
+    "echo" : {
+      "request" : [ {
+        "name" : "record",
+        "type" : "TestRecord"
+      } ],
+      "response" : "TestRecord"
+    },
+    "add" : {
+      "request" : [ {
+        "name" : "arg1",
+        "type" : "int"
+      }, {
+        "name" : "arg2",
+        "type" : "int"
+      } ],
+      "response" : "int"
+    },
+    "echoBytes" : {
+      "request" : [ {
+        "name" : "data",
+        "type" : "bytes"
+      } ],
+      "response" : "bytes"
+    },
+    "error" : {
+      "request" : [ ],
+      "response" : "null",
+      "errors" : [ "TestError" ]
+    }
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/genavro/output/unicode.avpr
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/genavro/output/unicode.avpr?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/genavro/output/unicode.avpr (added)
+++ hadoop/avro/trunk/src/test/genavro/output/unicode.avpr Thu Dec 31 20:23:22 2009
@@ -0,0 +1,17 @@
+{
+  "protocol" : "Протоколы",
+  "namespace" : null,
+  "types" : [ {
+    "type" : "record",
+    "name" : "Структура",
+    "fields" : [ {
+      "name" : "Строковый",
+      "type" : "string"
+    }, {
+      "name" : "文字列",
+      "type" : "string"
+    } ]
+  } ],
+  "messages" : {
+  }
+}
\ No newline at end of file

Added: hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/TestGenAvro.java
URL: http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/TestGenAvro.java?rev=894933&view=auto
==============================================================================
--- hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/TestGenAvro.java (added)
+++ hadoop/avro/trunk/src/test/java/org/apache/avro/genavro/TestGenAvro.java Thu Dec 31 20:23:22 2009
@@ -0,0 +1,155 @@
+/**
+ * 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.avro.genavro;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import org.apache.avro.Protocol;
+
+/**
+ * Simple test harness for GenAvro.
+ * This relies on an input/ and output/ directory. Inside
+ * the input/ directory are .genavro files. Each file should have
+ * a corresponding .avpr file in output/. When the test is run,
+ * it generates and stringifies each .genavro file and compares
+ * it to the expected output, failing if the two differ.
+ *
+ * To make it simpler to write these tests, you can run
+ *   ant -Dtestcase=TestGenAvro -Dtest.genavro.mode=write
+ * which will *replace* all expected output.
+ */
+public class TestGenAvro {
+  private static final File TEST_DIR =
+    new File(System.getProperty("test.genavro.dir"));
+
+  private static final File TEST_INPUT_DIR =
+    new File(TEST_DIR, "input");
+
+  private static final File TEST_OUTPUT_DIR =
+    new File(TEST_DIR, "output");
+
+  private static final String TEST_MODE =
+    System.getProperty("test.genavro.mode", "run");
+
+  private List<GenTest> tests;
+
+  @Before
+  public void loadTests() {
+    assertTrue(TEST_DIR.exists());
+    assertTrue(TEST_INPUT_DIR.exists());
+    assertTrue(TEST_OUTPUT_DIR.exists());
+
+    tests = new ArrayList<GenTest>();
+    for (File inF : TEST_INPUT_DIR.listFiles()) {
+      if (!inF.getName().endsWith(".genavro")) continue;
+      if (inF.getName().startsWith(".")) continue;
+
+      File outF = new File(
+        TEST_OUTPUT_DIR,
+        inF.getName().replaceFirst("\\.genavro$", ".avpr"));
+      tests.add(new GenTest(inF, outF));
+    }
+  }
+
+  @Test
+  public void runTests() throws Exception {
+    if (! "run".equals(TEST_MODE)) return;
+
+    int passed = 0, failed = 0;
+    
+    for (GenTest t : tests) {
+      try {
+        t.run();
+        passed++;
+      } catch (Exception e) {
+        failed++;
+        e.printStackTrace(System.err);
+      }
+    }
+
+    if (failed > 0) {
+      fail(String.valueOf(failed) + " tests failed");
+    }
+  }
+
+  @Test
+  public void writeTests() throws Exception {
+    if (! "write".equals(TEST_MODE)) return;
+
+    for (GenTest t : tests) {
+      t.write();
+    }
+  }
+
+
+  /**
+   * An invididual comparison test
+   */
+  private static class GenTest {
+    private final File in, expectedOut;
+
+    public GenTest(File in, File expectedOut) {
+      this.in = in;
+      this.expectedOut = expectedOut;
+    }
+
+    private String generate() throws Exception {
+      GenAvro parser = new GenAvro(new FileInputStream(in), "UTF-8");
+      Protocol p = parser.CompilationUnit();
+      return p.toString(true);
+    }
+
+    public void run() throws Exception {
+      String output = generate();
+      String slurped = slurp(expectedOut);
+      assertEquals(slurped.trim(), output.trim());
+    }
+
+    public void write() throws Exception {
+      writeFile(expectedOut, generate());
+    }
+
+    private static String slurp(File f) throws IOException {
+      BufferedReader in = new BufferedReader(new FileReader(f));
+
+      String line = null;
+      StringBuilder builder = new StringBuilder();
+      while ((line = in.readLine()) != null) {
+        builder.append(line).append('\n');
+      }
+      return builder.toString();
+    }
+
+    private static void writeFile(File f, String s) throws IOException {
+      FileWriter w = new FileWriter(f);
+      w.write(s);
+      w.close();
+    }
+  }
+}



Mime
View raw message