1919import org .agrona .MutableDirectBuffer ;
2020import org .agrona .Strings ;
2121import org .agrona .Verify ;
22- import org .agrona .generation .OutputManager ;
22+ import org .agrona .generation .DynamicPackageOutputManager ;
2323import org .agrona .sbe .*;
2424import uk .co .real_logic .sbe .PrimitiveType ;
2525import uk .co .real_logic .sbe .generation .CodeGenerator ;
3030import java .io .Writer ;
3131import java .util .ArrayList ;
3232import java .util .Formatter ;
33+ import java .util .HashSet ;
3334import java .util .List ;
35+ import java .util .Set ;
3436import java .util .function .Function ;
3537
3638import static uk .co .real_logic .sbe .SbeTool .JAVA_INTERFACE_PACKAGE ;
@@ -60,14 +62,40 @@ enum CodecType
6062 private static final String INDENT = " " ;
6163
6264 private final Ir ir ;
63- private final OutputManager outputManager ;
65+ private final DynamicPackageOutputManager outputManager ;
6466 private final String fqMutableBuffer ;
6567 private final String mutableBuffer ;
6668 private final String fqReadOnlyBuffer ;
6769 private final String readOnlyBuffer ;
6870 private final boolean shouldGenerateGroupOrderAnnotation ;
6971 private final boolean shouldGenerateInterfaces ;
7072 private final boolean shouldDecodeUnknownEnumValues ;
73+ private final boolean shouldSupportTypePackages ;
74+ private final Set <String > typePackages = new HashSet <>();
75+
76+ /**
77+ * Create a new Java language {@link CodeGenerator}. Generator support for types in their own package is disabled.
78+ *
79+ * @param ir for the messages and types.
80+ * @param mutableBuffer implementation used for mutating underlying buffers.
81+ * @param readOnlyBuffer implementation used for reading underlying buffers.
82+ * @param shouldGenerateGroupOrderAnnotation in the codecs.
83+ * @param shouldGenerateInterfaces for common methods.
84+ * @param shouldDecodeUnknownEnumValues generate support for unknown enum values when decoding.
85+ * @param outputManager for generating the codecs to.
86+ */
87+ public JavaGenerator (
88+ final Ir ir ,
89+ final String mutableBuffer ,
90+ final String readOnlyBuffer ,
91+ final boolean shouldGenerateGroupOrderAnnotation ,
92+ final boolean shouldGenerateInterfaces ,
93+ final boolean shouldDecodeUnknownEnumValues ,
94+ final DynamicPackageOutputManager outputManager )
95+ {
96+ this (ir , mutableBuffer , readOnlyBuffer , shouldGenerateGroupOrderAnnotation , shouldGenerateInterfaces ,
97+ shouldDecodeUnknownEnumValues , false , outputManager );
98+ }
7199
72100 /**
73101 * Create a new Java language {@link CodeGenerator}.
@@ -78,6 +106,7 @@ enum CodecType
78106 * @param shouldGenerateGroupOrderAnnotation in the codecs.
79107 * @param shouldGenerateInterfaces for common methods.
80108 * @param shouldDecodeUnknownEnumValues generate support for unknown enum values when decoding.
109+ * @param shouldSupportTypePackages generator support for types in their own package
81110 * @param outputManager for generating the codecs to.
82111 */
83112 public JavaGenerator (
@@ -87,12 +116,14 @@ public JavaGenerator(
87116 final boolean shouldGenerateGroupOrderAnnotation ,
88117 final boolean shouldGenerateInterfaces ,
89118 final boolean shouldDecodeUnknownEnumValues ,
90- final OutputManager outputManager )
119+ final boolean shouldSupportTypePackages ,
120+ final DynamicPackageOutputManager outputManager )
91121 {
92122 Verify .notNull (ir , "ir" );
93123 Verify .notNull (outputManager , "outputManager" );
94124
95125 this .ir = ir ;
126+ this .shouldSupportTypePackages = shouldSupportTypePackages ;
96127 this .outputManager = outputManager ;
97128
98129 this .mutableBuffer = validateBufferImplementation (mutableBuffer , MutableDirectBuffer .class );
@@ -144,11 +175,30 @@ public void generateTypeStubs() throws IOException
144175 }
145176 }
146177
178+ /**
179+ * Register the the type's explicit package - if it's set and should be supported.
180+ *
181+ * @param token the 0-th token of the type
182+ * @param ir the intermediate representation
183+ * @return the overriden package name of the type if set and supported, or {@link Ir#applicableNamespace() }
184+ */
185+ private String registerTypePackage (final Token token , final Ir ir )
186+ {
187+ if (shouldSupportTypePackages && token .packageName () != null )
188+ {
189+ typePackages .add (token .packageName ());
190+ outputManager .setPackageName (token .packageName ());
191+ return token .packageName ();
192+ }
193+ return ir .applicableNamespace ();
194+ }
195+
147196 /**
148197 * {@inheritDoc}
149198 */
150199 public void generate () throws IOException
151200 {
201+ typePackages .clear ();
152202 generatePackageInfo ();
153203 generateTypeStubs ();
154204 generateMessageHeaderStub ();
@@ -1188,6 +1238,7 @@ private void generateBitSet(final List<Token> tokens) throws IOException
11881238 final List <Token > choiceList = tokens .subList (1 , tokens .size () - 1 );
11891239 final String implementsString = implementsInterface (Flyweight .class .getSimpleName ());
11901240
1241+ registerTypePackage (token , ir );
11911242 try (Writer out = outputManager .createOutput (decoderName ))
11921243 {
11931244 final Encoding encoding = token .encoding ();
@@ -1208,6 +1259,7 @@ private void generateBitSet(final List<Token> tokens) throws IOException
12081259 out .append ("}\n " );
12091260 }
12101261
1262+ registerTypePackage (token , ir );
12111263 try (Writer out = outputManager .createOutput (encoderName ))
12121264 {
12131265 generateFixedFlyweightHeader (out , token , encoderName , implementsString , mutableBuffer , fqMutableBuffer );
@@ -1225,7 +1277,8 @@ private void generateFixedFlyweightHeader(
12251277 final String buffer ,
12261278 final String fqBuffer ) throws IOException
12271279 {
1228- out .append (generateFileHeader (ir .applicableNamespace (), fqBuffer ));
1280+ final String packageName = registerTypePackage (token , ir );
1281+ out .append (generateFileHeader (packageName , fqBuffer ));
12291282 out .append (generateDeclaration (typeName , implementsString , token ));
12301283 out .append (generateFixedFlyweightCode (typeName , token .encodedLength (), buffer ));
12311284 }
@@ -1238,7 +1291,8 @@ private void generateCompositeFlyweightHeader(
12381291 final String fqBuffer ,
12391292 final String implementsString ) throws IOException
12401293 {
1241- out .append (generateFileHeader (ir .applicableNamespace (), fqBuffer ));
1294+ final String packageName = registerTypePackage (token , ir );
1295+ out .append (generateFileHeader (packageName , fqBuffer ));
12421296 out .append (generateDeclaration (typeName , implementsString , token ));
12431297 out .append (generateFixedFlyweightCode (typeName , token .encodedLength (), buffer ));
12441298 }
@@ -1250,9 +1304,10 @@ private void generateEnum(final List<Token> tokens) throws IOException
12501304 final Encoding encoding = enumToken .encoding ();
12511305 final String nullVal = encoding .applicableNullValue ().toString ();
12521306
1307+ final String packageName = registerTypePackage (enumToken , ir );
12531308 try (Writer out = outputManager .createOutput (enumName ))
12541309 {
1255- out .append (generateEnumFileHeader (ir . applicableNamespace () ));
1310+ out .append (generateEnumFileHeader (packageName ));
12561311 out .append (generateEnumDeclaration (enumName , enumToken ));
12571312
12581313 final List <Token > valuesList = tokens .subList (1 , tokens .size () - 1 );
@@ -1272,6 +1327,7 @@ private void generateComposite(final List<Token> tokens) throws IOException
12721327 final String decoderName = decoderName (compositeName );
12731328 final String encoderName = encoderName (compositeName );
12741329
1330+ registerTypePackage (token , ir );
12751331 try (Writer out = outputManager .createOutput (decoderName ))
12761332 {
12771333 final String implementsString = implementsInterface (CompositeDecoderFlyweight .class .getSimpleName ());
@@ -1320,6 +1376,7 @@ private void generateComposite(final List<Token> tokens) throws IOException
13201376 out .append ("}\n " );
13211377 }
13221378
1379+ registerTypePackage (token , ir );
13231380 try (Writer out = outputManager .createOutput (encoderName ))
13241381 {
13251382 final String implementsString = implementsInterface (CompositeEncoderFlyweight .class .getSimpleName ());
@@ -1572,13 +1629,22 @@ private CharSequence generateFileHeader(final String packageName, final String f
15721629 private CharSequence generateMainHeader (
15731630 final String packageName , final CodecType codecType , final boolean hasVarData )
15741631 {
1632+ final StringBuffer packageImports = new StringBuffer ();
1633+ for (final String typePackage : typePackages )
1634+ {
1635+ packageImports .append ("import " );
1636+ packageImports .append (typePackage );
1637+ packageImports .append (".*;\n " );
1638+ }
1639+
15751640 if (fqMutableBuffer .equals (fqReadOnlyBuffer ))
15761641 {
15771642 return
15781643 "/* Generated SBE (Simple Binary Encoding) message codec. */\n " +
15791644 "package " + packageName + ";\n \n " +
15801645 "import " + fqMutableBuffer + ";\n " +
1581- interfaceImportLine ();
1646+ interfaceImportLine () +
1647+ packageImports .toString ();
15821648 }
15831649 else
15841650 {
@@ -1590,7 +1656,8 @@ private CharSequence generateMainHeader(
15901656 "package " + packageName + ";\n \n " +
15911657 (hasMutableBuffer ? "import " + fqMutableBuffer + ";\n " : "" ) +
15921658 (hasReadOnlyBuffer ? "import " + fqReadOnlyBuffer + ";\n " : "" ) +
1593- interfaceImportLine ();
1659+ interfaceImportLine () +
1660+ packageImports .toString ();
15941661 }
15951662 }
15961663
0 commit comments