Permalink
Browse files

Add Pegasus data schema language (.pdl).

  • Loading branch information...
1 parent 22172dd commit 07a72f32b7c8b9bbcd3988de2666a37a3fbab397 @jpbetz jpbetz committed Dec 7, 2016
Showing with 4,246 additions and 343 deletions.
  1. +2 −2 CHANGELOG
  2. +2 −0 build.gradle
  3. +2 −1 build_script/dataTemplate.gradle
  4. +2 −1 build_script/restModel.gradle
  5. +1 −0 data/.gitignore
  6. +26 −1 data/build.gradle
  7. +205 −0 data/src/main/antlr/com/linkedin/data/grammar/Pdl.g4
  8. +66 −3 data/src/main/java/com/linkedin/data/schema/AbstractSchemaParser.java
  9. +7 −0 data/src/main/java/com/linkedin/data/schema/DataSchemaParserFactory.java
  10. +1 −60 data/src/main/java/com/linkedin/data/schema/SchemaParser.java
  11. +9 −1 data/src/main/java/com/linkedin/data/schema/SchemaParserFactory.java
  12. +2 −2 data/src/main/java/com/linkedin/data/schema/generator/AbstractGenerator.java
  13. +174 −0 data/src/main/java/com/linkedin/data/schema/grammar/PdlParseUtils.java
  14. +984 −0 data/src/main/java/com/linkedin/data/schema/grammar/PdlSchemaParser.java
  15. +47 −0 data/src/main/java/com/linkedin/data/schema/grammar/PdlSchemaParserFactory.java
  16. +20 −13 data/src/main/java/com/linkedin/data/schema/resolver/AbstractDataSchemaResolver.java
  17. +30 −0 data/src/main/java/com/linkedin/data/schema/resolver/FileDataSchemaResolver.java
  18. +133 −0 data/src/main/java/com/linkedin/data/schema/resolver/MultiFormatDataSchemaResolver.java
  19. +91 −0 data/src/test/java/com/linkedin/data/schema/grammar/TestPdlParseUtils.java
  20. +6 −0 generator-test/build.gradle
  21. +158 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/ArrayGeneratorTest.java
  22. +40 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/FixedGeneratorTest.java
  23. +80 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/GeneratorTest.java
  24. +168 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/MapGeneratorTest.java
  25. +368 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/RecordGeneratorTest.java
  26. +36 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/SchemaFixtures.java
  27. +73 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/TyperefGeneratorTest.java
  28. +121 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/UnionGeneratorTest.java
  29. +35 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/fixtures/CustomInt.java
  30. +32 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/fixtures/CustomIntCoercer.java
  31. +103 −0 generator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/fixtures/CustomRecord.java
  32. +41 −0 ...ator-test/src/test/java/com/linkedin/pegasus/generator/test/pdl/fixtures/CustomRecordCoercer.java
  33. +7 −0 generator-test/src/test/json/FortuneCookie.json
  34. +15 −0 generator-test/src/test/json/Fortune_FortuneCookie.json
  35. +9 −0 generator-test/src/test/json/Fortune_MagicEightBall.json
  36. +3 −0 generator-test/src/test/json/KeywordEscaping.json
  37. +4 −0 generator-test/src/test/json/Message.json
  38. +4 −0 generator-test/src/test/json/Message_wrongFieldType.json
  39. +6 −0 generator-test/src/test/json/ReservedClassFieldEscaping.json
  40. +1 −0 generator-test/src/test/json/Simple.json
  41. +9 −0 generator-test/src/test/json/WithComplexTypes.json
  42. +28 −0 generator-test/src/test/json/WithComplexTypesMap.json
  43. +5 −0 generator-test/src/test/json/WithComplexTypesUnion_Array.json
  44. +5 −0 generator-test/src/test/json/WithComplexTypesUnion_Empty.json
  45. +5 −0 generator-test/src/test/json/WithComplexTypesUnion_Enum.json
  46. +5 −0 generator-test/src/test/json/WithComplexTypesUnion_Map.json
  47. +11 −0 generator-test/src/test/json/WithCustomTypesArray.json
  48. +11 −0 generator-test/src/test/json/WithCustomTypesArrayMutable.json
  49. +7 −0 generator-test/src/test/json/WithCustomTypesMap.json
  50. +3 −0 generator-test/src/test/json/WithDateTime.json
  51. +3 −0 generator-test/src/test/json/WithPrimitiveCustomTypes.json
  52. +5 −0 generator-test/src/test/json/WithPrimitiveCustomTypesUnion_int.json
  53. +9 −0 generator-test/src/test/json/WithPrimitives.json
  54. +10 −0 generator-test/src/test/json/WithPrimitivesArray.json
  55. +37 −0 generator-test/src/test/json/WithPrimitivesMap.json
  56. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_boolean.json
  57. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_bytes.json
  58. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_double.json
  59. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_float.json
  60. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_int.json
  61. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_long.json
  62. +5 −0 generator-test/src/test/json/WithPrimitivesUnion_string.json
  63. +9 −0 generator-test/src/test/json/WithPrimitives_flex_defaults.json
  64. +4 −0 generator-test/src/test/json/WithRecordArray.json
  65. +14 −0 generator-test/src/test/json/WithTypedKeyMap.json
  66. +8 −0 generator-test/src/test/json/WithUnion.json
  67. +5 −0 generator-test/src/test/json/WithUnion_malformedMember.json
  68. +3 −0 generator-test/src/test/json/WithUnion_malformedTag.json
  69. +6 −0 ...-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/arrays/WithAnonymousUnionArray.pdl
  70. +15 −0 ...tor-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/arrays/WithCustomTypesArray.pdl
  71. +11 −0 ...ator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/arrays/WithPrimitivesArray.pdl
  72. +9 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/arrays/WithRecordArray.pdl
  73. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/customtypes/CustomInt.pdl
  74. +7 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/customtypes/CustomRecord.pdl
  75. +11 −0 ...tor-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/deprecated/DeprecatedRecord.pdl
  76. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/enums/EmptyEnum.pdl
  77. +12 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/enums/EnumProperties.pdl
  78. +15 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/enums/Fruits.pdl
  79. +5 −0 ...test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/escaping/DefaultLiteralEscaping.pdl
  80. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/escaping/KeywordEscaping.pdl
  81. +8 −0 .../src/test/pegasus/com/linkedin/pegasus/generator/test/idl/escaping/ReservedClassFieldEscaping.pdl
  82. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/escaping/class.pdl
  83. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/fixed/Fixed8.pdl
  84. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/fixed/WithFixed8.pdl
  85. +8 −0 ...rator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/interop/WithPdlReference.pdsc
  86. +7 −0 ...rator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/interop/WithPdscReference.pdl
  87. +6 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/maps/Toggle.pdl
  88. +18 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/maps/WithComplexTypesMap.pdl
  89. +7 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/maps/WithCustomTypesMap.pdl
  90. +11 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/maps/WithPrimitivesMap.pdl
  91. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/Empty.pdl
  92. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/Empty2.pdl
  93. +7 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/JsonTest.pdl
  94. +6 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/Message.pdl
  95. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/Note.pdl
  96. +8 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/NumericDefaults.pdl
  97. +5 −0 ...est/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/RecursivelyDefinedRecord.pdl
  98. +11 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/Simple.pdl
  99. +13 −0 ...test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithComplexTypeDefaults.pdl
  100. +15 −0 ...tor-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithComplexTyperefs.pdl
  101. +14 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithComplexTypes.pdl
  102. +9 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithCustomRecord.pdl
  103. +6 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithInclude.pdl
  104. +10 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithInlineRecord.pdl
  105. +13 −0 .../test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalComplexTypeDefaults.pdl
  106. +14 −0 ...est/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalComplexTypes.pdl
  107. +8 −0 ...test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalPrimitiveCustomTypes.pdl
  108. +14 −0 ...rc/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalPrimitiveDefaults.pdl
  109. +11 −0 ...rc/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalPrimitiveTyperefs.pdl
  110. +11 −0 ...-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithOptionalPrimitives.pdl
  111. +8 −0 ...est/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithPrimitiveCustomTypes.pdl
  112. +14 −0 ...r-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithPrimitiveDefaults.pdl
  113. +11 −0 ...r-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithPrimitiveTyperefs.pdl
  114. +11 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithPrimitives.pdl
  115. +7 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithUnion.pdl
  116. +7 −0 ...st/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/WithUnionWithInlineRecord.pdl
  117. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/records/class.pdl
  118. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/ArrayTyperef.pdl
  119. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/EnumTyperef.pdl
  120. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/IntTyperef.pdl
  121. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/MapTyperef.pdl
  122. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/RecordTyperef.pdl
  123. +6 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/Union.pdl
  124. +3 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/UnionTyperef.pdl
  125. +10 −0 ...-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/typerefs/UnionWithInlineRecord.pdl
  126. +9 −0 ...or-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/unions/WithComplexTypesUnion.pdl
  127. +5 −0 generator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/unions/WithEmptyUnion.pdl
  128. +9 −0 ...src/test/pegasus/com/linkedin/pegasus/generator/test/idl/unions/WithPrimitiveCustomTypesUnion.pdl
  129. +5 −0 ...ator-test/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/unions/WithPrimitivesUnion.pdl
  130. +7 −0 ...est/src/test/pegasus/com/linkedin/pegasus/generator/test/idl/unions/WithRecordCustomTypeUnion.pdl
  131. +2 −3 generator/src/main/java/com/linkedin/pegasus/generator/CodeUtil.java
  132. +102 −242 generator/src/main/java/com/linkedin/pegasus/generator/DataSchemaParser.java
  133. +278 −0 generator/src/main/java/com/linkedin/pegasus/generator/FileFormatDataSchemaParser.java
  134. +1 −0 gradle-plugins/src/main/groovy/com/linkedin/pegasus/gradle/SharedFileUtils.groovy
  135. +1 −1 gradle.properties
  136. +2 −3 ...i-int-test/src/test/java/com/linkedin/restli/test/TestResourceSchemaToResourceSpecTranslator.java
  137. +3 −2 restli-tools/src/main/java/com/linkedin/restli/tools/compatibility/CompatibilityUtil.java
  138. +2 −3 ...ols/src/main/java/com/linkedin/restli/tools/idlcheck/RestLiResourceModelCompatibilityChecker.java
  139. +4 −5 ...tools/src/test/java/com/linkedin/restli/tools/compatibility/TestResourceCompatibilityChecker.java
View
@@ -1,6 +1,6 @@
-10.0.3
+10.1.0
------
-
+Introduce .pdl file format for authoring Pegasus data schemas.
10.0.2
------
View
@@ -28,6 +28,7 @@ apply from: environmentScript
apply from: "${buildScriptDirPath}/configBuildScript.gradle"
project.ext.externalDependency = [
+ 'antlr': 'org.antlr:antlr4:4.5',
'avro': 'org.apache.avro:avro:1.4.0',
'avro_1_6': 'org.apache.avro:avro:1.6.3',
'cglib': 'cglib:cglib-nodep:2.2',
@@ -38,6 +39,7 @@ project.ext.externalDependency = [
'commonsHttpClient': 'commons-httpclient:commons-httpclient:3.1',
'commonsIo': 'commons-io:commons-io:2.4',
'commonsLang': 'commons-lang:commons-lang:2.4',
+ 'commonsLang3': 'org.apache.commons:commons-lang3:3.4',
'disruptor': 'com.lmax:disruptor:3.2.0',
'easymock': 'org.easymock:easymock:3.1',
'mockito': 'org.mockito:mockito-all:1.9.5',
@@ -22,7 +22,7 @@ project.sourceSets.all { SourceSet sourceSet ->
final String inputDataSchemaParentDirPath = "src${File.separatorChar}${sourceSet.name}"
final String pegasusDirName = 'pegasus'
final String inputDataSchemaDirPath = "${inputDataSchemaParentDirPath}${File.separatorChar}${pegasusDirName}"
- final FileTree inputDataSchemaFiles = project.fileTree(dir: inputDataSchemaDirPath, includes: ["**${File.separatorChar}*.pdsc"])
+ final FileTree inputDataSchemaFiles = project.fileTree(dir: inputDataSchemaDirPath, includes: ["**${File.separatorChar}*.pdsc", "**${File.separatorChar}*.pdl"])
if (inputDataSchemaFiles.empty)
{
return;
@@ -45,6 +45,7 @@ project.sourceSets.all { SourceSet sourceSet ->
final Task jarTask = project.tasks[sourceSet.getTaskName('', 'jar')]
jarTask.from(inputDataSchemaParentDirPath) {
include "${pegasusDirName}${File.separatorChar}**${File.separatorChar}*.pdsc"
+ include "${pegasusDirName}${File.separatorChar}**${File.separatorChar}*.pdl"
}
final Task dataTemplateCompileTask = project.task(sourceSet.name + 'CompileDataTemplate',
@@ -38,7 +38,7 @@ project.sourceSets.all { SourceSet sourceSet ->
// data template generation task
final String pegasusDirName = 'pegasus'
final String inputDataSchemaDirPath = "${inputParentDirPath}${File.separatorChar}${pegasusDirName}"
- final FileTree inputDataSchemaFiles = project.fileTree(dir: inputDataSchemaDirPath, includes: ["**${File.separatorChar}*.pdsc"])
+ final FileTree inputDataSchemaFiles = project.fileTree(dir: inputDataSchemaDirPath, includes: ["**${File.separatorChar}*.pdsc", "**${File.separatorChar}*.pdl"])
if (!inputDataSchemaFiles.empty) {
final String outputDataTemplateDirPath = rootProject.ext.build.getDataTemplateOutDirPath(project, sourceSet)
sourceSet.java.srcDir(outputDataTemplateDirPath)
@@ -82,6 +82,7 @@ project.sourceSets.all { SourceSet sourceSet ->
final Task jarTask = project.tasks[sourceSet.getTaskName('', 'jar')]
jarTask.from(inputParentDirPath) {
include "${pegasusDirName}${File.separatorChar}**${File.separatorChar}*.pdsc"
+ include "${pegasusDirName}${File.separatorChar}**${File.separatorChar}*.pdl"
include "${idlDirName}${File.separatorChar}**${File.separatorChar}*.restspec.json\""
}
}
View
@@ -0,0 +1 @@
+src/mainGeneratedAntlr
View
@@ -1,8 +1,14 @@
+apply plugin: 'antlr'
+
dependencies {
- compile externalDependency.jacksonCore
+ compile externalDependency.antlr
+ compile externalDependency.commonsLang3
compile externalDependency.guava
+ compile externalDependency.jacksonCore
testCompile externalDependency.commonsIo
testCompile externalDependency.testng
+
+ antlr externalDependency.antlr
}
test {
@@ -11,3 +17,22 @@ test {
forkEvery = 1
maxParallelForks = 4
}
+
+def generatedAntlrDir = file("src/mainGeneratedAntlr")
+def generatedAntlrJavaDir = file("${generatedAntlrDir}/java")
+
+generateGrammarSource {
+ outputDirectory = file("${generatedAntlrJavaDir}/com/linkedin/data/schema/grammar")
+}
+
+sourceSets.main.java {
+ srcDir generatedAntlrJavaDir
+}
+
+idea.module {
+ generatedSourceDirs += generatedAntlrJavaDir
+}
+
+clean {
+ delete generatedAntlrDir
+}
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2015 Coursera Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Antlr grammar for the Pegasus data language format (.pdl).
+ */
+grammar Pdl;
+
+@header {
+ package com.linkedin.data.grammar;
+
+ import com.linkedin.data.schema.grammar.PdlParseUtils;
+ import java.util.Arrays;
+}
+
+// Document is the top level node of this grammar.
+// Each .pdl file contains exactly one document.
+document: namespaceDeclaration? importDeclarations namedTypeDeclaration;
+
+namespaceDeclaration: NAMESPACE qualifiedIdentifier;
+
+importDeclarations: importDeclaration*;
+
+importDeclaration: IMPORT type=qualifiedIdentifier;
+
+// A typeReference is simply a type name that refers to a type defined elsewhere.
+typeReference returns [String value]: qualifiedIdentifier {
+ $value = $qualifiedIdentifier.value;
+};
+
+typeDeclaration: namedTypeDeclaration | anonymousTypeDeclaration;
+
+// Only named declarations support schemadoc and properties.
+namedTypeDeclaration: doc=schemadoc? props+=propDeclaration*
+ (recordDeclaration | enumDeclaration | typerefDeclaration | fixedDeclaration);
+
+anonymousTypeDeclaration: unionDeclaration | arrayDeclaration | mapDeclaration;
+
+typeAssignment: typeReference | typeDeclaration;
+
+// Each property is a node in a properties tree, keyed by it's path in the tree.
+// The value of each property may be any JSON type.
+// If the property does not specify a property, it defaults to JSON 'true'.
+propDeclaration returns [String name, List<String> path]: propNameDeclaration propJsonValue? {
+ $name = $propNameDeclaration.name;
+ $path = Arrays.asList($propNameDeclaration.name.split("\\."));
+};
+
+propNameDeclaration returns [String name]: AT qualifiedIdentifier {
+ $name = $qualifiedIdentifier.value;
+};
+
+propJsonValue: EQ jsonValue;
+
+recordDeclaration returns [String name]: RECORD identifier recordDecl=fieldSelection {
+ $name = $identifier.value;
+};
+
+enumDeclaration returns [String name]: ENUM identifier enumDecl=enumSymbolDeclarations {
+ $name = $identifier.value;
+};
+
+enumSymbolDeclarations: OPEN_BRACE symbolDecls+=enumSymbolDeclaration* CLOSE_BRACE;
+
+enumSymbolDeclaration: doc=schemadoc? props+=propDeclaration* symbol=enumSymbol;
+
+enumSymbol returns [String value]: identifier {
+ $value = $identifier.value;
+};
+
+typerefDeclaration returns [String name]: TYPEREF identifier EQ ref=typeAssignment {
+ $name = $identifier.value;
+};
+
+fixedDeclaration returns[String name, int size]:
+ FIXED identifier sizeStr=NUMBER_LITERAL {
+ $name = $identifier.value;
+ $size = $sizeStr.int;
+};
+
+unionDeclaration: UNION typeParams=unionTypeAssignments;
+
+unionTypeAssignments: OPEN_BRACKET members+=unionMemberDeclaration* CLOSE_BRACKET;
+
+unionMemberDeclaration: member=typeAssignment;
+
+arrayDeclaration: ARRAY typeParams=arrayTypeAssignments;
+
+arrayTypeAssignments: OPEN_BRACKET items=typeAssignment CLOSE_BRACKET;
+
+mapDeclaration: MAP typeParams=mapTypeAssignments;
+
+mapTypeAssignments: OPEN_BRACKET key=typeAssignment value=typeAssignment CLOSE_BRACKET;
+
+fieldSelection: OPEN_BRACE fields+=fieldSelectionElement* CLOSE_BRACE;
+
+fieldSelectionElement: fieldInclude | fieldDeclaration;
+
+fieldInclude: DOTDOTDOT typeReference;
+
+fieldDeclaration returns [String name, boolean isOptional]:
+ doc=schemadoc? props+=propDeclaration* fieldName=identifier COLON type=typeAssignment QUESTION_MARK?
+ fieldDefault? {
+ $name = $identifier.value;
+ $isOptional = $QUESTION_MARK() != null;
+};
+
+fieldDefault: EQ jsonValue;
+
+// A qualified identifier is simply one or more '.' separated identifiers.
+qualifiedIdentifier returns [String value]: ID (DOT ID)* {
+ $value = PdlParseUtils.unescapeIdentifier($text);
+};
+
+identifier returns [String value]: ID {
+ $value = PdlParseUtils.unescapeIdentifier($text);
+};
+
+// Schemadoc strings support markdown formatting.
+schemadoc returns [String value]: SCHEMADOC_COMMENT {
+ $value = PdlParseUtils.extractMarkdown($SCHEMADOC_COMMENT.text);
+};
+
+// Embedded JSON Grammar
+// JSON is used both for property values and for field default values.
+object: OPEN_BRACE objectEntry* CLOSE_BRACE;
+
+objectEntry: key=string COLON value=jsonValue ;
+
+array: OPEN_BRACKET items=jsonValue* CLOSE_BRACKET;
+
+jsonValue: string | number | object | array | bool | nullValue;
+
+string returns [String value]: STRING_LITERAL {
+ $value = PdlParseUtils.extractString($STRING_LITERAL.text);
+};
+
+number returns [Number value]: NUMBER_LITERAL {
+ $value = PdlParseUtils.toNumber($NUMBER_LITERAL.text);
+};
+
+bool returns [Boolean value]: BOOLEAN_LITERAL {
+ $value = Boolean.valueOf($BOOLEAN_LITERAL.text);
+};
+
+nullValue: NULL_LITERAL;
+
+// Tokens
+// Antlr uses the below token rules to construct it the lexer for this grammar.
+ARRAY: 'array';
+ENUM: 'enum';
+FIXED: 'fixed';
+IMPORT: 'import';
+MAP: 'map';
+NAMESPACE: 'namespace';
+RECORD: 'record';
+TYPEREF: 'typeref';
+UNION: 'union';
+
+OPEN_PAREN: '(';
+CLOSE_PAREN: ')';
+OPEN_BRACE: '{';
+CLOSE_BRACE: '}';
+OPEN_BRACKET: '[';
+CLOSE_BRACKET: ']';
+
+AT: '@';
+COLON: ':';
+DOT: '.';
+DOTDOTDOT: '...';
+EQ: '=';
+QUESTION_MARK: '?';
+
+BOOLEAN_LITERAL: 'true' | 'false';
+NULL_LITERAL: 'null';
+
+SCHEMADOC_COMMENT: '/**' .*? '*/';
+BLOCK_COMMENT: '/*' .*? '*/' -> skip;
+LINE_COMMENT: '//' ~['\r\n']* -> skip;
+
+NUMBER_LITERAL: '-'? ('0' | [1-9] [0-9]*) ( '.' [0-9]+)? ([eE][+-]?[0-9]+)?;
+
+fragment HEX: [0-9a-fA-F];
+fragment UNICODE: 'u' HEX HEX HEX HEX;
+fragment ESC: '\\' (["\\/bfnrt] | UNICODE);
+STRING_LITERAL: '"' (ESC | ~["\\])* '"';
+
+ID: '`'? [A-Za-z_] [A-Za-z0-9_]* '`'?; // Avro/Pegasus identifiers with Scala/Swift escaping
+
+// "insignificant commas" are used in this grammar. Commas may be added as desired
+// in source files, but they are treated as whitespace.
+WS: [ \t\n\r\f,]+ -> skip;
Oops, something went wrong.

0 comments on commit 07a72f3

Please sign in to comment.