diff --git a/lib/src/main/java/thriftlabs/thriftfmt/FormatterUtil.java b/lib/src/main/java/thriftlabs/thriftfmt/FormatterUtil.java index 8c0e6bc..4252101 100644 --- a/lib/src/main/java/thriftlabs/thriftfmt/FormatterUtil.java +++ b/lib/src/main/java/thriftlabs/thriftfmt/FormatterUtil.java @@ -173,6 +173,8 @@ public void process(PureThriftFormatter formatter, ParseTree node) { public static final NodeProcessFunc defaultInline = genInlineContext(" ", null); + public static final NodeProcessFunc tightInline = genInlineContext("", null); + public static final NodeProcessFunc listSeparatorInline = genInlineContext( " ", (index, node) -> node instanceof ThriftParser.List_separatorContext); diff --git a/lib/src/main/java/thriftlabs/thriftfmt/PureThriftFormatter.java b/lib/src/main/java/thriftlabs/thriftfmt/PureThriftFormatter.java index 3b3840b..4259dd2 100644 --- a/lib/src/main/java/thriftlabs/thriftfmt/PureThriftFormatter.java +++ b/lib/src/main/java/thriftlabs/thriftfmt/PureThriftFormatter.java @@ -282,15 +282,15 @@ protected void IntegerContext(ThriftParser.IntegerContext node) { } protected void Container_typeContext(ThriftParser.Container_typeContext node) { - FormatterUtil.defaultInline.process(this, node); + FormatterUtil.tightInline.process(this, node); } protected void Set_typeContext(ThriftParser.Set_typeContext node) { - FormatterUtil.defaultInline.process(this, node); + FormatterUtil.tightInline.process(this, node); } protected void List_typeContext(ThriftParser.List_typeContext node) { - FormatterUtil.defaultInline.process(this, node); + FormatterUtil.tightInline.process(this, node); } protected void Cpp_typeContext(ThriftParser.Cpp_typeContext node) { @@ -310,7 +310,7 @@ protected void List_separatorContext(ThriftParser.List_separatorContext node) { } protected void Field_idContext(ThriftParser.Field_idContext node) { - FormatterUtil.defaultInline.process(this, node); + FormatterUtil.tightInline.process(this, node); } protected void Field_reqContext(ThriftParser.Field_reqContext node) { diff --git a/lib/src/main/java/thriftlabs/thriftfmt/ThriftFormatter.java b/lib/src/main/java/thriftlabs/thriftfmt/ThriftFormatter.java index 5df71c9..5122460 100644 --- a/lib/src/main/java/thriftlabs/thriftfmt/ThriftFormatter.java +++ b/lib/src/main/java/thriftlabs/thriftfmt/ThriftFormatter.java @@ -1,6 +1,6 @@ package thriftlabs.thriftfmt; -public class ThriftFormatter { +public class ThriftFormatter extends PureThriftFormatter { public ThriftFormatter() { } } diff --git a/lib/src/test/java/thriftlabs/thriftfmt/PureThriftFormatterTest.java b/lib/src/test/java/thriftlabs/thriftfmt/PureThriftFormatterTest.java index d193144..0195cf8 100644 --- a/lib/src/test/java/thriftlabs/thriftfmt/PureThriftFormatterTest.java +++ b/lib/src/test/java/thriftlabs/thriftfmt/PureThriftFormatterTest.java @@ -1,6 +1,18 @@ package thriftlabs.thriftfmt; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; import org.junit.Test; @@ -15,4 +27,47 @@ public void TestSimpleFormatter() { var content = formatter.formatNode(result.document); assertEquals("include \"shared.thrift\"", content); } + + @SuppressWarnings("resource") + private String readResourceFile(String fileName) { + ClassLoader classLoader = getClass().getClassLoader(); + try (InputStream inputStream = classLoader.getResourceAsStream(fileName)) { + if (inputStream == null) { + throw new IllegalArgumentException("File not found: " + fileName); + } + return new Scanner(inputStream, StandardCharsets.UTF_8.name()).useDelimiter("\\A").next(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + @Test + public void testFindThriftFiles() { + String directory = "src/test/resources/thrifts"; // 资源目录 + try { + List thriftFiles = findThriftFiles(directory); + thriftFiles.forEach(path -> testFormatterFile(path)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private List findThriftFiles(String directory) throws IOException { + Path dirPath = Paths.get(directory); + return Files.walk(dirPath) + .filter(path -> path.toString().endsWith(".thrift")) + .map(Path::getFileName) + .map(Path::toString) + .collect(Collectors.toList()); + } + + public void testFormatterFile(String fileName) { + String content = readResourceFile("thrifts/" + fileName); + assertNotNull("Fixture file should be found", content); + + Thrift.ParserResult result = Thrift.parse(content); + var formatter = new PureThriftFormatter(); + formatter.formatNode(result.document); + } } diff --git a/lib/src/test/resources/thrifts/AnnotationTest.thrift b/lib/src/test/resources/thrifts/AnnotationTest.thrift new file mode 100644 index 0000000..1a2d2a1 --- /dev/null +++ b/lib/src/test/resources/thrifts/AnnotationTest.thrift @@ -0,0 +1,70 @@ +/* + * 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. + */ + +typedef list( cpp.template = "std::list" ) int_linked_list + +struct foo { + 1: required i32 bar ( presence = "required" ), + 2: required i32 baz ( presence = "manual", cpp.use_pointer = "" ), + 3: required i32 qux, + 4: required i32 bop, +} ( cpp.type = "DenseFoo", python.type = "DenseFoo", java.final = "", annotation.without.value ) + +const string default_user = "\'default_user\'" ; +const string default_name = '"abc\'s"' ; + +exception foo_error { + 1: required i32 error_code ( foo = "bar\'" ), + 2: required string error_msg, +} ( foo = "bar" ) + +typedef string ( unicode.encoding = "UTF-16" ) non_latin_string ( foo = "bar" ) +typedef list tiny_float_list + +enum weekdays { + SUNDAY ( weekend = "yes" ), + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY ( weekend = "yes" ), +} ( foo.bar = "baz" ) + +/* Note that annotations on senum values are not supported. */ + +struct ostr_default { + 1: required i32 bar, +} + +struct ostr_custom { + 1: required i32 bar, +} ( cpp.customostream ) + +service foo_service { + void foo() ( foo = "bar" ), +} ( a.b = "c" ) + +service deprecate_everything { + # TODO: fix LITERAL + void Foo() ( deprecated = "This method has neither 'x' nor \"y\"" ), + void Bar() ( deprecated = "Fails to deliver 中文 колбаса" ), + void Baz() ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" ), + void Deprecated() ( deprecated ), // no comment +} \ No newline at end of file diff --git a/lib/src/test/resources/thrifts/README.md b/lib/src/test/resources/thrifts/README.md new file mode 100644 index 0000000..c64bef0 --- /dev/null +++ b/lib/src/test/resources/thrifts/README.md @@ -0,0 +1,21 @@ +Thrift Tutorial + +License +======= + +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. diff --git a/lib/src/test/resources/thrifts/ThriftTest.thrift b/lib/src/test/resources/thrifts/ThriftTest.thrift new file mode 100644 index 0000000..3f4514c --- /dev/null +++ b/lib/src/test/resources/thrifts/ThriftTest.thrift @@ -0,0 +1,414 @@ +/* + * 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. + * + * Contains some contributions under the Thrift Software License. + * Please see doc/old-thrift-license.txt in the Thrift distribution for + * details. + */ + +namespace c_glib TTest +namespace cpp thrift.test +namespace delphi Thrift.Test +namespace go thrifttest +namespace java thrift.test +namespace js ThriftTest +namespace lua ThriftTest +namespace netstd ThriftTest +namespace perl ThriftTest +namespace php ThriftTest +namespace py ThriftTest +namespace py.twisted ThriftTest +namespace rb Thrift.Test +namespace st ThriftTest +namespace xsd test (uri = 'http://thrift.apache.org/ns/ThriftTest') + +// Presence of namespaces and sub-namespaces for which there is +// no generator should compile with warnings only +namespace noexist ThriftTest +namespace cpp.noexist ThriftTest + +namespace * thrift.test + +/** + * Docstring! + */ +enum Numberz +{ + ONE = 1, + TWO, + THREE, + FIVE = 5, + SIX, + EIGHT = 8 +} + +const Numberz myNumberz = Numberz.ONE; +// the following is expected to fail: +// const Numberz urNumberz = ONE; + +typedef i64 UserId + +struct Bonk +{ + 1: string message, + 2: i32 type +} + +typedef map MapType + +struct Bools { + 1: bool im_true, + 2: bool im_false, +} + +struct Xtruct +{ + 1: string string_thing, + 4: i8 byte_thing, + 9: i32 i32_thing, + 11: i64 i64_thing +} + +struct Xtruct2 +{ + 1: i8 byte_thing, // used to be byte, hence the name + 2: Xtruct struct_thing, + 3: i32 i32_thing // a +} + +struct Xtruct3 +{ + 1: string string_thing, + 4: i32 changed, + 9: i32 i32_thing, + 11: i64 i64_thing +} + + +struct Insanity +{ + 1: map userMap, + 2: list xtructs +} (python.immutable= "") + + +struct CrazyNesting { + 1: string string_field, + 2: optional set set_field, + // Do not insert line break as test/go/Makefile.am is removing this line with pattern match + 3: required list (python.immutable = ""), map(python.immutable = "")> (python.immutable = "")>>>> list_field, + 4: binary binary_field +} + +union SomeUnion { + 1: map map_thing, + 2: string string_thing, + 3: i32 i32_thing, + 4: Xtruct3 xtruct_thing, + 5: Insanity insanity_thing +} + +exception Xception { + 1: i32 errorCode, + 2: string message +} + +exception Xception2 { + 1: i32 errorCode, + 2: Xtruct struct_thing +} + +struct EmptyStruct {} + +struct OneField { + 1: EmptyStruct field +} + +service ThriftTest +{ + /** + * Prints "testVoid()" and returns nothing. + */ + void testVoid(), + + /** + * Prints 'testString("%s")' with thing as '%s' + * @param string thing - the string to print + * @return string - returns the string 'thing' + */ + string testString(1: string thing), + + /** + * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false' + * @param bool thing - the bool data to print + * @return bool - returns the bool 'thing' + */ + bool testBool(1: bool thing), + + /** + * Prints 'testByte("%d")' with thing as '%d' + * The types i8 and byte are synonyms, use of i8 is encouraged, byte still exists for the sake of compatibility. + * @param byte thing - the i8/byte to print + * @return i8 - returns the i8/byte 'thing' + */ + i8 testByte(1: i8 thing), + + /** + * Prints 'testI32("%d")' with thing as '%d' + * @param i32 thing - the i32 to print + * @return i32 - returns the i32 'thing' + */ + i32 testI32(1: i32 thing), + + /** + * Prints 'testI64("%d")' with thing as '%d' + * @param i64 thing - the i64 to print + * @return i64 - returns the i64 'thing' + */ + i64 testI64(1: i64 thing), + + /** + * Prints 'testDouble("%f")' with thing as '%f' + * @param double thing - the double to print + * @return double - returns the double 'thing' + */ + double testDouble(1: double thing), + + /** + * Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data + * @param binary thing - the binary data to print + * @return binary - returns the binary 'thing' + */ + binary testBinary(1: binary thing), + + /** + * Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values + * @param Xtruct thing - the Xtruct to print + * @return Xtruct - returns the Xtruct 'thing' + */ + Xtruct testStruct(1: Xtruct thing), + + /** + * Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct + * @param Xtruct2 thing - the Xtruct2 to print + * @return Xtruct2 - returns the Xtruct2 'thing' + */ + Xtruct2 testNest(1: Xtruct2 thing), + + /** + * Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs + * separated by commas and new lines + * @param map thing - the map to print + * @return map - returns the map 'thing' + */ + map testMap(1: map thing), + + /** + * Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs + * separated by commas and new lines + * @param map thing - the map to print + * @return map - returns the map 'thing' + */ + map testStringMap(1: map thing), + + /** + * Prints 'testSet("{%s}")' where thing has been formatted into a string of values + * separated by commas and new lines + * @param set thing - the set to print + * @return set - returns the set 'thing' + */ + set testSet(1: set thing), + + /** + * Prints 'testList("{%s}")' where thing has been formatted into a string of values + * separated by commas and new lines + * @param list thing - the list to print + * @return list - returns the list 'thing' + */ + list testList(1: list thing), + + /** + * Prints 'testEnum("%d")' where thing has been formatted into its numeric value + * @param Numberz thing - the Numberz to print + * @return Numberz - returns the Numberz 'thing' + */ + Numberz testEnum(1: Numberz thing), + + /** + * Prints 'testTypedef("%d")' with thing as '%d' + * @param UserId thing - the UserId to print + * @return UserId - returns the UserId 'thing' + */ + UserId testTypedef(1: UserId thing), + + /** + * Prints 'testMapMap("%d")' with hello as '%d' + * @param i32 hello - the i32 to print + * @return map> - returns a dictionary with these values: + * {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } + */ + map> testMapMap(1: i32 hello), + + /** + * So you think you've got this all worked out, eh? + * + * Creates a map with these values and prints it out: + * { 1 => { 2 => argument, + * 3 => argument, + * }, + * 2 => { 6 => , }, + * } + * @return map> - a map with the above values + */ + map> testInsanity(1: Insanity argument), + + /** + * Prints 'testMulti()' + * @param i8 arg0 - + * @param i32 arg1 - + * @param i64 arg2 - + * @param map arg3 - + * @param Numberz arg4 - + * @param UserId arg5 - + * @return Xtruct - returns an Xtruct with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1 + * and i64_thing = arg2 + */ + Xtruct testMulti(1: i8 arg0, 2: i32 arg1, 3: i64 arg2, 4: map arg3, 5: Numberz arg4, 6: UserId arg5), + + /** + * Print 'testException(%s)' with arg as '%s' + * @param string arg - a string indication what type of exception to throw + * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg + * else if arg == "TException" throw TException + * else do not throw anything + */ + void testException(1: string arg) throws(1: Xception err1), + + /** + * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' + * @param string arg - a string indicating what type of exception to throw + * if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" + * else if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and struct_thing.string_thing = "This is an Xception2" + * else do not throw anything + * @return Xtruct - an Xtruct with string_thing = arg1 + */ + Xtruct testMultiException(1: string arg0, 2: string arg1) throws(1: Xception err1, 2: Xception2 err2) + + /** + * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' + * sleep 'secondsToSleep' + * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' + * @param i32 secondsToSleep - the number of seconds to sleep + */ + oneway void testOneway(1:i32 secondsToSleep) +} + +service SecondService +{ + /** + * Prints 'testString("%s")' with thing as '%s' + * @param string thing - the string to print + * @return string - returns the string 'thing' + */ + string secondtestString(1: string thing) +} + +struct VersioningTestV1 { + 1: i32 begin_in_both, + 3: string old_string, + 12: i32 end_in_both +} + +struct VersioningTestV2 { + 1: i32 begin_in_both, + + 2: i32 newint, + 3: i8 newbyte, + 4: i16 newshort, + 5: i64 newlong, + 6: double newdouble + 7: Bonk newstruct, + 8: list newlist, + 9: set newset, + 10: map newmap, + 11: string newstring, + 12: i32 end_in_both +} + +struct ListTypeVersioningV1 { + 1: list myints; + 2: string hello; +} + +struct ListTypeVersioningV2 { + 1: list strings; + 2: string hello; +} + +struct GuessProtocolStruct { + 7: map map_field, +} + +struct LargeDeltas { + 1: Bools b1, + 10: Bools b10, + 100: Bools b100, + 500: bool check_true, + 1000: Bools b1000, + 1500: bool check_false, + 2000: VersioningTestV2 vertwo2000, + 2500: set a_set2500, + 3000: VersioningTestV2 vertwo3000, + 4000: list big_numbers +} + +struct NestedListsI32x2 { + 1: list> integerlist +} +struct NestedListsI32x3 { + 1: list>> integerlist +} +struct NestedMixedx2 { + 1: list> int_set_list + 2: map> map_int_strset + 3: list>> map_int_strset_list +} +struct ListBonks { + 1: list bonk +} +struct NestedListsBonk { + 1: list>> bonk +} + +struct BoolTest { + 1: optional bool b = true; + 2: optional string s = "true"; +} + +struct StructA { + 1: required string s; +} + +struct StructB { + 1: optional StructA aa; + 2: required StructA ab; +} + +struct OptionalSetDefaultTest { + 1: optional set with_default = [ "test", "hello", ] +} diff --git a/lib/src/test/resources/thrifts/namespace.thrift b/lib/src/test/resources/thrifts/namespace.thrift new file mode 100644 index 0000000..add4444 --- /dev/null +++ b/lib/src/test/resources/thrifts/namespace.thrift @@ -0,0 +1 @@ +namespace xsd test (uri = 'http://thrift.apache.org/ns/ThriftTest', test = 1) \ No newline at end of file diff --git a/lib/src/test/resources/thrifts/shared.thrift b/lib/src/test/resources/thrifts/shared.thrift new file mode 100644 index 0000000..b67f709 --- /dev/null +++ b/lib/src/test/resources/thrifts/shared.thrift @@ -0,0 +1,46 @@ +/* + * 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 Thrift file can be included by other Thrift files that want to share + * these definitions. + */ + +/* +namespace cl shared +namespace cpp shared +namespace d share // "shared" would collide with the eponymous D keyword. +namespace dart shared +namespace java shared +namespace perl shared +namespace php shared +namespace haxe shared +namespace netstd shared +*/ +namespace py shared + + +struct SharedStruct { + 1: i32 key + 2: string value +} + +service SharedService { + SharedStruct getStruct(1: i32 key) +} \ No newline at end of file diff --git a/lib/src/test/resources/thrifts/simple.thrift b/lib/src/test/resources/thrifts/simple.thrift new file mode 100644 index 0000000..e02eb8b --- /dev/null +++ b/lib/src/test/resources/thrifts/simple.thrift @@ -0,0 +1,42 @@ +/*x + + y*/ + +// hello +include "shared.thrift" // hello3 + +/*x + + y*/ + +# a +// b +include "shared2.thrift" //a + +// gt + +/*xyz +*/ + +struct Xtruct2 { + 1: required i8 byte_thing, // used to be byte, hence the name + 2: required Xtruct struct_thing, // b + 3: required i32 i32_thing, // a +} + +struct Work { + 1: required i32 num1 = 0, + 2: required i32 num2, // num2 for + // 3: required Operation op, // op is Operation + 4: optional string comment, + 5: required map> tags, //hello +} + +struct Person { + 1: list tags, + 2: optional list opt_tags, + 3: required list req_tags, + 4: string name, + 5: optional string opt_name, + 6: required string req_name, +} diff --git a/lib/src/test/resources/thrifts/tutorial.thrift b/lib/src/test/resources/thrifts/tutorial.thrift new file mode 100644 index 0000000..738970d --- /dev/null +++ b/lib/src/test/resources/thrifts/tutorial.thrift @@ -0,0 +1,127 @@ +/* + * 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. + * + * Contains some contributions under the Thrift Software License. + * Please see doc/old-thrift-license.txt in the Thrift distribution for + * details. + */ + + +include "shared.thrift" + +/** + * Thrift files can namespace, package, or prefix their output in various + * target languages. + */ +/* +namespace cl tutorial +namespace cpp tutorial +namespace d tutorial +namespace dart tutorial +namespace java tutorial +namespace php tutorial +namespace perl tutorial +namespace haxe tutorial +namespace netstd tutorial +*/ +namespace py tutorial + +/** + * Thrift lets you do typedefs to get pretty names for your types. Standard + * C style here. + */ +typedef i32 MyInteger + +/** + * Thrift also lets you define constants for use across languages. Complex + * types and structs are specified using JSON notation. + */ +const i32 INT32CONSTANT = 9853 +const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} +const double DOUBLE_CONSTANT = 98.53333333222 +const double DOUBLE_CONSTANT2 = 1.35E10 +/** + * You can define enums, which are just 32 bit integers. Values are optional + * and start at 1 if not supplied, C style again. + */ +enum Operation { + ADD = 1, + SUBTRACT = 2, + MULTIPLY = 3, + DIVIDE = 4; + LESS = -1; +} + +/** + * Structs are the basic complex data structures. They are comprised of fields + * which each have an integer identifier, a type, a symbolic name, and an + * optional default value. + * + * Fields can be declared "optional", which ensures they will not be included + * in the serialized output if they aren't set. Note that this requires some + * manual management in some languages. + */ +struct Work { + 1: i32 num1 = 0, + 2: i32 num2, // num2 for + 3: Operation op, // op is Operation + 4: optional string comment, +} + +/** + * Structs can also be exceptions, if they are nasty. + */ +exception InvalidOperation { + 1: i32 whatOp, + 2: string why = "ok? what the dog"; +} + +/** + * Ahh, now onto the cool part, defining a service. Services just need a name + * and can optionally inherit from another service using the extends keyword. + */ +service Calculator extends shared.SharedService { + + /** + * A method definition looks like C code. It has a return type, arguments, + * and optionally a list of exceptions that it may throw. Note that argument + * lists and exception lists are specified using the exact same syntax as + * field lists in struct or exception definitions. + */ + + void ping(), + + i32 add(1:i32 num1, 2:i32 num2), + + i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), + + /** + * This method has a oneway modifier. That means the client only makes + * a request and does not listen for any response at all. Oneway methods + * must be void. + */ + oneway void zip() + +} + +/** + * That just about covers the basics. Take a look in the test/ folder for more + * detailed examples. After you run this file, your generated code shows up + * in folders with names gen-. The generated code isn't too scary + * to look at. It even has pretty indentation. + */ \ No newline at end of file