structurize 2.18.1__tar.gz → 2.19.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {structurize-2.18.1/structurize.egg-info → structurize-2.19.0}/PKG-INFO +1 -1
  2. {structurize-2.18.1 → structurize-2.19.0}/avrotize/_version.py +3 -3
  3. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocsharp.py +21 -2
  4. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojava.py +90 -36
  5. structurize-2.19.0/avrotize/cddltostructure.py +1841 -0
  6. {structurize-2.18.1 → structurize-2.19.0}/avrotize/commands.json +226 -0
  7. structurize-2.19.0/avrotize/constants.py +72 -0
  8. structurize-2.19.0/avrotize/dependencies/cpp/vcpkg/vcpkg.json +19 -0
  9. structurize-2.19.0/avrotize/dependencies/typescript/node22/package.json +16 -0
  10. structurize-2.19.0/avrotize/dependency_version.py +432 -0
  11. structurize-2.19.0/avrotize/structuretocddl.py +597 -0
  12. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocsharp.py +311 -21
  13. structurize-2.19.0/avrotize/structuretojava.py +853 -0
  14. {structurize-2.18.1 → structurize-2.19.0/structurize.egg-info}/PKG-INFO +1 -1
  15. {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/SOURCES.txt +24 -0
  16. structurize-2.18.1/avrotize/constants.py +0 -5
  17. {structurize-2.18.1 → structurize-2.19.0}/.gitignore +0 -0
  18. {structurize-2.18.1 → structurize-2.19.0}/LICENSE +0 -0
  19. {structurize-2.18.1 → structurize-2.19.0}/MANIFEST.in +0 -0
  20. {structurize-2.18.1 → structurize-2.19.0}/README.md +0 -0
  21. {structurize-2.18.1 → structurize-2.19.0}/avrotize/__init__.py +0 -0
  22. {structurize-2.18.1 → structurize-2.19.0}/avrotize/__main__.py +0 -0
  23. {structurize-2.18.1 → structurize-2.19.0}/avrotize/asn1toavro.py +0 -0
  24. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotize.py +0 -0
  25. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocpp.py +0 -0
  26. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocsv.py +0 -0
  27. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotodatapackage.py +0 -0
  28. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotodb.py +0 -0
  29. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotogo.py +0 -0
  30. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotographql.py +0 -0
  31. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoiceberg.py +0 -0
  32. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojs.py +0 -0
  33. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojsons.py +0 -0
  34. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojstruct.py +0 -0
  35. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotokusto.py +0 -0
  36. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotomd.py +0 -0
  37. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotools.py +0 -0
  38. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoparquet.py +0 -0
  39. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoproto.py +0 -0
  40. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotopython.py +0 -0
  41. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotorust.py +0 -0
  42. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotots.py +0 -0
  43. {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoxsd.py +0 -0
  44. {structurize-2.18.1 → structurize-2.19.0}/avrotize/common.py +0 -0
  45. {structurize-2.18.1 → structurize-2.19.0}/avrotize/csvtoavro.py +0 -0
  46. {structurize-2.18.1 → structurize-2.19.0}/avrotize/datapackagetoavro.py +0 -0
  47. {structurize-2.18.1 → structurize-2.19.0}/avrotize/dependency_resolver.py +0 -0
  48. {structurize-2.18.1 → structurize-2.19.0}/avrotize/jsonstoavro.py +0 -0
  49. {structurize-2.18.1 → structurize-2.19.0}/avrotize/jsonstostructure.py +0 -0
  50. {structurize-2.18.1 → structurize-2.19.0}/avrotize/jstructtoavro.py +0 -0
  51. {structurize-2.18.1 → structurize-2.19.0}/avrotize/kstructtoavro.py +0 -0
  52. {structurize-2.18.1 → structurize-2.19.0}/avrotize/kustotoavro.py +0 -0
  53. {structurize-2.18.1 → structurize-2.19.0}/avrotize/parquettoavro.py +0 -0
  54. {structurize-2.18.1 → structurize-2.19.0}/avrotize/proto2parser.py +0 -0
  55. {structurize-2.18.1 → structurize-2.19.0}/avrotize/proto3parser.py +0 -0
  56. {structurize-2.18.1 → structurize-2.19.0}/avrotize/prototoavro.py +0 -0
  57. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocpp.py +0 -0
  58. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocsv.py +0 -0
  59. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretodatapackage.py +0 -0
  60. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretodb.py +0 -0
  61. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretogo.py +0 -0
  62. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretographql.py +0 -0
  63. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoiceberg.py +0 -0
  64. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretojsons.py +0 -0
  65. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretokusto.py +0 -0
  66. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretomd.py +0 -0
  67. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoproto.py +0 -0
  68. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretopython.py +0 -0
  69. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretorust.py +0 -0
  70. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretots.py +0 -0
  71. {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoxsd.py +0 -0
  72. {structurize-2.18.1 → structurize-2.19.0}/avrotize/xsdtoavro.py +0 -0
  73. {structurize-2.18.1 → structurize-2.19.0}/build.ps1 +0 -0
  74. {structurize-2.18.1 → structurize-2.19.0}/build.sh +0 -0
  75. {structurize-2.18.1 → structurize-2.19.0}/pyproject.toml +0 -0
  76. {structurize-2.18.1 → structurize-2.19.0}/setup.cfg +0 -0
  77. {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/dependency_links.txt +0 -0
  78. {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/entry_points.txt +0 -0
  79. {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/requires.txt +0 -0
  80. {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 2.18.1
3
+ Version: 2.19.0
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '2.18.1'
32
- __version_tuple__ = version_tuple = (2, 18, 1)
31
+ __version__ = version = '2.19.0'
32
+ __version_tuple__ = version_tuple = (2, 19, 0)
33
33
 
34
- __commit_id__ = commit_id = 'gdae473138'
34
+ __commit_id__ = commit_id = 'geec8f9840'
@@ -9,6 +9,15 @@ from typing import Any, Dict, List, Tuple, Union, cast
9
9
  import uuid
10
10
 
11
11
  from avrotize.common import build_flat_type_dict, inline_avro_references, is_generic_avro_type, pascal, process_template
12
+ from avrotize.constants import (
13
+ CSHARP_AVRO_VERSION,
14
+ NEWTONSOFT_JSON_VERSION,
15
+ SYSTEM_TEXT_JSON_VERSION,
16
+ SYSTEM_MEMORY_DATA_VERSION,
17
+ NUNIT_VERSION,
18
+ NUNIT_ADAPTER_VERSION,
19
+ MSTEST_SDK_VERSION,
20
+ )
12
21
  import glob
13
22
 
14
23
  JsonNode = Dict[str, 'JsonNode'] | List['JsonNode'] | str | None
@@ -957,7 +966,14 @@ class AvroToCSharp:
957
966
  avro_annotation=self.avro_annotation,
958
967
  system_xml_annotation=self.system_xml_annotation,
959
968
  system_text_json_annotation=self.system_text_json_annotation,
960
- newtonsoft_json_annotation=self.newtonsoft_json_annotation))
969
+ newtonsoft_json_annotation=self.newtonsoft_json_annotation,
970
+ CSHARP_AVRO_VERSION=CSHARP_AVRO_VERSION,
971
+ NEWTONSOFT_JSON_VERSION=NEWTONSOFT_JSON_VERSION,
972
+ SYSTEM_TEXT_JSON_VERSION=SYSTEM_TEXT_JSON_VERSION,
973
+ SYSTEM_MEMORY_DATA_VERSION=SYSTEM_MEMORY_DATA_VERSION,
974
+ NUNIT_VERSION=NUNIT_VERSION,
975
+ NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
976
+ MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
961
977
  if not glob.glob(os.path.join(output_dir, "test", "*.csproj")):
962
978
  csproj_test_file = os.path.join(
963
979
  output_dir, "test", f"{pascal(project_name)}.Test.csproj")
@@ -971,7 +987,10 @@ class AvroToCSharp:
971
987
  avro_annotation=self.avro_annotation,
972
988
  system_xml_annotation=self.system_xml_annotation,
973
989
  system_text_json_annotation=self.system_text_json_annotation,
974
- newtonsoft_json_annotation=self.newtonsoft_json_annotation))
990
+ newtonsoft_json_annotation=self.newtonsoft_json_annotation,
991
+ NUNIT_VERSION=NUNIT_VERSION,
992
+ NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
993
+ MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
975
994
 
976
995
  self.output_dir = output_dir
977
996
  for avro_schema in (avs for avs in schema if isinstance(avs, dict)):
@@ -4,7 +4,8 @@
4
4
  import json
5
5
  import os
6
6
  from typing import Dict, List, Tuple, Union
7
- from avrotize.constants import AVRO_VERSION, JACKSON_VERSION, JDK_VERSION
7
+ from avrotize.constants import (AVRO_VERSION, JACKSON_VERSION, JDK_VERSION,
8
+ JUNIT_VERSION, MAVEN_COMPILER_VERSION, MAVEN_SUREFIRE_VERSION)
8
9
 
9
10
  from avrotize.common import pascal, camel, is_generic_avro_type, inline_avro_references, build_flat_type_dict
10
11
 
@@ -46,13 +47,13 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
46
47
  <dependency>
47
48
  <groupId>org.junit.jupiter</groupId>
48
49
  <artifactId>junit-jupiter-api</artifactId>
49
- <version>5.10.0</version>
50
+ <version>{JUNIT_VERSION}</version>
50
51
  <scope>test</scope>
51
52
  </dependency>
52
53
  <dependency>
53
54
  <groupId>org.junit.jupiter</groupId>
54
55
  <artifactId>junit-jupiter-engine</artifactId>
55
- <version>5.10.0</version>
56
+ <version>{JUNIT_VERSION}</version>
56
57
  <scope>test</scope>
57
58
  </dependency>
58
59
  </dependencies>
@@ -61,7 +62,7 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
61
62
  <plugin>
62
63
  <groupId>org.apache.maven.plugins</groupId>
63
64
  <artifactId>maven-compiler-plugin</artifactId>
64
- <version>3.11.0</version>
65
+ <version>{MAVEN_COMPILER_VERSION}</version>
65
66
  <configuration>
66
67
  <compilerArgs>
67
68
  <arg>-Xmaxerrs</arg>
@@ -72,7 +73,7 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
72
73
  <plugin>
73
74
  <groupId>org.apache.maven.plugins</groupId>
74
75
  <artifactId>maven-surefire-plugin</artifactId>
75
- <version>3.0.0-M9</version>
76
+ <version>{MAVEN_SUREFIRE_VERSION}</version>
76
77
  <configuration>
77
78
  <useSystemClassLoader>false</useSystemClassLoader>
78
79
  </configuration>
@@ -693,7 +694,8 @@ class AvroToJava:
693
694
  elif items_type in self.generated_types_java_package:
694
695
  kind = self.generated_types_java_package[items_type]
695
696
  if kind == "enum":
696
- pred += f"n.elements().next().isTextual() && Enum.valueOf({items_type}.class, n.elements().next().asText()) != null"
697
+ # Try to match the incoming text against Avro symbols
698
+ pred += f"n.elements().next().isTextual() && java.util.Arrays.stream({items_type}.values()).anyMatch(e -> e.avroSymbol().equals(n.elements().next().asText()))"
697
699
  else:
698
700
  pred += f"{items_type}.isJsonMatch(n.elements().next())"
699
701
  else:
@@ -710,7 +712,8 @@ class AvroToJava:
710
712
  elif values_type in self.generated_types_java_package:
711
713
  kind = self.generated_types_java_package[values_type]
712
714
  if kind == "enum":
713
- pred += f"n.elements().next().isTextual() && Enum.valueOf({values_type}.class, n.elements().next().asText()) != null"
715
+ # Try to match the incoming text against Avro symbols
716
+ pred += f"n.elements().next().isTextual() && java.util.Arrays.stream({values_type}.values()).anyMatch(e -> e.avroSymbol().equals(n.elements().next().asText()))"
714
717
  else:
715
718
  pred += f"{values_type}.isJsonMatch(n.elements().next())"
716
719
  else:
@@ -730,7 +733,8 @@ class AvroToJava:
730
733
  raw_const = const_value if isinstance(const_value, str) else str(const_value)
731
734
  class_definition += f"(node.has(\"{field_name_js}\") && node.get(\"{field_name_js}\").isTextual() && node.get(\"{field_name_js}\").asText().equals(\"{raw_const}\"))"
732
735
  else:
733
- class_definition += f"(node.get(\"{field_name_js}\").isTextual() && Enum.valueOf({field_type.type_name}.class, node.get(\"{field_name_js}\").asText()) != null)"
736
+ # Try to match the incoming text against Avro symbols
737
+ class_definition += f"(node.get(\"{field_name_js}\").isTextual() && java.util.Arrays.stream({field_type.type_name}.values()).anyMatch(e -> e.avroSymbol().equals(node.get(\"{field_name_js}\").asText())))"
734
738
  else:
735
739
  is_union = False
736
740
  field_union = pascal(field_name) + 'Union'
@@ -802,7 +806,8 @@ class AvroToJava:
802
806
  elif field_type.is_class:
803
807
  class_definition += f"({null_check} || {field_type.type_name}.isJsonMatch({element_name}))"
804
808
  elif field_type.is_enum:
805
- class_definition += f"({null_check} || ({node_check}.isTextual() && Enum.valueOf({field_type.type_name}.class, {element_name}.asText()) != null))"
809
+ # Try to match the incoming text against Avro symbols
810
+ class_definition += f"({null_check} || ({node_check}.isTextual() && java.util.Arrays.stream({field_type.type_name}.values()).anyMatch(e -> e.avroSymbol().equals({element_name}.asText()))))"
806
811
  else:
807
812
  is_union = False
808
813
  field_union = pascal(element_name) + 'Union'
@@ -1022,8 +1027,8 @@ class AvroToJava:
1022
1027
  get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? this.{field_name}.entrySet().stream().collect(java.util.stream.Collectors.toMap(java.util.Map.Entry::getKey, e -> e.getValue() != null ? e.getValue().toObject() : null)) : null;\n"
1023
1028
  elif field_type.is_enum:
1024
1029
  # For enum fields, convert to GenericEnumSymbol for Avro serialization
1025
- # This allows SpecificDatumWriter to serialize enums inside unions correctly
1026
- get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? new GenericData.EnumSymbol({field_type.type_name}.SCHEMA, this.{field_name}.name()) : null;\n"
1030
+ # Use avroSymbol() to get the original Avro symbol name for serialization
1031
+ get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? new GenericData.EnumSymbol({field_type.type_name}.SCHEMA, this.{field_name}.avroSymbol()) : null;\n"
1027
1032
  else:
1028
1033
  # For all other field types, return the field as-is
1029
1034
  # Avro's SpecificDatumWriter will handle serialization internally
@@ -1104,7 +1109,8 @@ class AvroToJava:
1104
1109
  put_method += f"{INDENT * 3}case {index}: this.{field_name} = value$ instanceof GenericData.Record ? new {field_type.type_name}((GenericData.Record)value$) : ({field_type.type_name})value$; break;\n"
1105
1110
  elif type_kind == "enum":
1106
1111
  # Enums need to be converted from GenericData.EnumSymbol
1107
- put_method += f"{INDENT * 3}case {index}: this.{field_name} = value$ instanceof GenericData.EnumSymbol ? {field_type.type_name}.valueOf(value$.toString()) : ({field_type.type_name})value$; break;\n"
1112
+ # Use fromAvroSymbol to match original Avro symbol names
1113
+ put_method += f"{INDENT * 3}case {index}: this.{field_name} = value$ instanceof GenericData.EnumSymbol ? {field_type.type_name}.fromAvroSymbol(value$.toString()) : ({field_type.type_name})value$; break;\n"
1108
1114
  else:
1109
1115
  # Check if this is a List<RecordType> or Map<String,RecordType>
1110
1116
  is_list_of_records = False
@@ -1164,10 +1170,11 @@ class AvroToJava:
1164
1170
  # Check if it's a List of enums
1165
1171
  if element_type in self.generated_types_java_package and self.generated_types_java_package[element_type] == "enum":
1166
1172
  # For List<Enum>, convert GenericEnumSymbol to actual enum values
1173
+ # Use fromAvroSymbol to match original Avro symbol names
1167
1174
  put_method += f"{INDENT * 3}case {index}: {{\n"
1168
1175
  put_method += f"{INDENT * 4}if (value$ instanceof List<?>) {{\n"
1169
1176
  put_method += f"{INDENT * 5}List<?> list = (List<?>)value$;\n"
1170
- put_method += f"{INDENT * 5}this.{field_name} = list.stream().map(item -> item instanceof GenericData.EnumSymbol ? {element_type}.valueOf(item.toString()) : ({element_type})item).collect(java.util.stream.Collectors.toList());\n"
1177
+ put_method += f"{INDENT * 5}this.{field_name} = list.stream().map(item -> item instanceof GenericData.EnumSymbol ? {element_type}.fromAvroSymbol(item.toString()) : ({element_type})item).collect(java.util.stream.Collectors.toList());\n"
1171
1178
  put_method += f"{INDENT * 4}}} else {{\n"
1172
1179
  put_method += f"{INDENT * 5}this.{field_name} = null;\n"
1173
1180
  put_method += f"{INDENT * 4}}}\n"
@@ -1211,20 +1218,44 @@ class AvroToJava:
1211
1218
  self.generated_types_java_package[type_name] = "enum"
1212
1219
  self.generated_avro_schemas[type_name] = avro_schema
1213
1220
  symbols = avro_schema.get('symbols', [])
1214
- # Convert symbols to valid Java identifiers, preserving case
1221
+ # Convert symbols to valid Java identifiers in SCREAMING_CASE (uppercase)
1215
1222
  # Replace invalid chars, prepend _ if starts with digit or is a reserved word
1223
+ # Keep track of mapping from Java symbol to original Avro symbol for serialization
1216
1224
  java_symbols = []
1225
+ symbol_pairs = [] # (java_symbol, avro_symbol) pairs
1217
1226
  for symbol in symbols:
1218
- java_symbol = symbol.replace('-', '_').replace('.', '_')
1227
+ java_symbol = symbol.replace('-', '_').replace('.', '_').upper()
1219
1228
  if java_symbol and java_symbol[0].isdigit():
1220
1229
  java_symbol = '_' + java_symbol
1221
1230
  # Check if the symbol is a Java reserved word and prefix with underscore
1222
- if is_java_reserved_word(java_symbol):
1231
+ if is_java_reserved_word(java_symbol.lower()):
1223
1232
  java_symbol = '_' + java_symbol
1224
1233
  java_symbols.append(java_symbol)
1225
- symbols_str = ', '.join(java_symbols)
1234
+ symbol_pairs.append((java_symbol, symbol))
1235
+
1236
+ # Build enum with avroSymbol field for proper Avro serialization
1226
1237
  enum_definition += f"public enum {enum_name} {{\n"
1227
- enum_definition += f"{INDENT}{symbols_str}"
1238
+ # Each enum constant has its original Avro symbol stored
1239
+ enum_constants = []
1240
+ for java_symbol, avro_symbol in symbol_pairs:
1241
+ enum_constants.append(f'{java_symbol}("{avro_symbol}")')
1242
+ enum_definition += f"{INDENT}" + ", ".join(enum_constants)
1243
+
1244
+ # Add avroSymbol field and method with Jackson annotations for proper JSON serialization
1245
+ enum_definition += f";\n\n{INDENT}private final String avroSymbol;\n\n"
1246
+ enum_definition += f"{INDENT}{enum_name}(String avroSymbol) {{\n{INDENT*2}this.avroSymbol = avroSymbol;\n{INDENT}}}\n\n"
1247
+ # @JsonValue tells Jackson to serialize the enum using avroSymbol() value
1248
+ enum_definition += f"{INDENT}@com.fasterxml.jackson.annotation.JsonValue\n"
1249
+ enum_definition += f"{INDENT}public String avroSymbol() {{\n{INDENT*2}return avroSymbol;\n{INDENT}}}\n\n"
1250
+
1251
+ # Add static lookup method to find enum by Avro symbol with @JsonCreator for deserialization
1252
+ enum_definition += f"{INDENT}@com.fasterxml.jackson.annotation.JsonCreator\n"
1253
+ enum_definition += f"{INDENT}public static {enum_name} fromAvroSymbol(String symbol) {{\n"
1254
+ enum_definition += f"{INDENT*2}for ({enum_name} e : values()) {{\n"
1255
+ enum_definition += f"{INDENT*3}if (e.avroSymbol.equals(symbol)) return e;\n"
1256
+ enum_definition += f"{INDENT*2}}}\n"
1257
+ enum_definition += f"{INDENT*2}throw new IllegalArgumentException(\"Unknown symbol: \" + symbol);\n"
1258
+ enum_definition += f"{INDENT}}}\n"
1228
1259
 
1229
1260
  # Add Avro schema if annotations are enabled
1230
1261
  if self.avro_annotation:
@@ -1245,9 +1276,7 @@ class AvroToJava:
1245
1276
  [enum_schema_json[i:i+80] for i in range(0, len(enum_schema_json), 80)])
1246
1277
  enum_schema_json = enum_schema_json.replace('§', '\\"')
1247
1278
 
1248
- enum_definition += f";\n\n{INDENT}public static final Schema SCHEMA = new Schema.Parser().parse(\n{INDENT}\"{enum_schema_json}\");\n"
1249
- else:
1250
- enum_definition += f";\n"
1279
+ enum_definition += f"\n{INDENT}public static final Schema SCHEMA = new Schema.Parser().parse(\n{INDENT}\"{enum_schema_json}\");\n"
1251
1280
 
1252
1281
  enum_definition += "}\n"
1253
1282
  if write_file:
@@ -1295,8 +1324,9 @@ class AvroToJava:
1295
1324
  f"{INDENT*1}public {union_type.type_name} get{union_variable_name}() {{ return _{camel(union_variable_name)}; }}\n";
1296
1325
 
1297
1326
  # For toObject(), wrap enums in GenericData.EnumSymbol so Avro can serialize them
1327
+ # Use avroSymbol() to get the original Avro symbol name for serialization
1298
1328
  if union_type.is_enum:
1299
- class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return new GenericData.EnumSymbol({union_type.type_name}.SCHEMA, _{camel(union_variable_name)}.name());\n{INDENT*2}}}\n"
1329
+ class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return new GenericData.EnumSymbol({union_type.type_name}.SCHEMA, _{camel(union_variable_name)}.avroSymbol());\n{INDENT*2}}}\n"
1300
1330
  else:
1301
1331
  class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return _{camel(union_variable_name)};\n{INDENT*2}}}\n"
1302
1332
 
@@ -1326,8 +1356,9 @@ class AvroToJava:
1326
1356
  class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof org.apache.avro.util.Utf8) {{\n{INDENT*3}this._{camel(union_variable_name)} = obj.toString();\n{INDENT*3}return;\n{INDENT*2}}}\n"
1327
1357
 
1328
1358
  # Handle Avro's GenericEnumSymbol for enum types
1359
+ # Use fromAvroSymbol to match original Avro symbol names
1329
1360
  if self.avro_annotation and union_type.is_enum:
1330
- class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof GenericData.EnumSymbol) {{\n{INDENT*3}this._{camel(union_variable_name)} = {union_type.type_name}.valueOf(obj.toString());\n{INDENT*3}return;\n{INDENT*2}}}\n"
1361
+ class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof GenericData.EnumSymbol) {{\n{INDENT*3}this._{camel(union_variable_name)} = {union_type.type_name}.fromAvroSymbol(obj.toString());\n{INDENT*3}return;\n{INDENT*2}}}\n"
1331
1362
 
1332
1363
  class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof {union_type.type_name}) {{\n{INDENT*3}this._{camel(union_variable_name)} = ({union_type.type_name})obj;\n{INDENT*3}return;\n{INDENT*2}}}\n"
1333
1364
 
@@ -1356,7 +1387,8 @@ class AvroToJava:
1356
1387
  else:
1357
1388
  # For classes and enums, use duck typing with isJsonMatch() (C# pattern)
1358
1389
  if union_type.is_enum:
1359
- class_definition_read += f"{INDENT*3}if (node.isTextual()) {{\n{INDENT*4}return new {union_class_name}(Enum.valueOf({union_type.type_name}.class, node.asText()));\n{INDENT*3}}}\n"
1390
+ # Use fromAvroSymbol to match original Avro symbol names
1391
+ class_definition_read += f"{INDENT*3}if (node.isTextual()) {{\n{INDENT*4}return new {union_class_name}({union_type.type_name}.fromAvroSymbol(node.asText()));\n{INDENT*3}}}\n"
1360
1392
  elif union_type.is_class:
1361
1393
  # Use isJsonMatch() to test if this type matches, then use fromData() to deserialize
1362
1394
  class_definition_read += f"{INDENT*3}if ({union_type.type_name}.isJsonMatch(node)) {{\n{INDENT*4}return new {union_class_name}({union_type.type_name}.fromData(node, \"application/json\"));\n{INDENT*3}}}\n"
@@ -1449,9 +1481,15 @@ class AvroToJava:
1449
1481
  const_value = field['const']
1450
1482
  is_discriminator = field.get('discriminator', False)
1451
1483
 
1452
- # For enum types, qualify with the enum type name
1484
+ # For enum types, qualify with the enum type name and convert to SCREAMING_CASE
1453
1485
  if field_type.type_name not in ('String', 'int', 'Integer', 'long', 'Long', 'double', 'Double', 'boolean', 'Boolean'):
1454
- const_value = f'{field_type.type_name}.{const_value}'
1486
+ # Convert enum const value to uppercase to match Java enum constant naming convention
1487
+ const_value_upper = str(const_value).replace('-', '_').replace('.', '_').upper()
1488
+ if const_value_upper and const_value_upper[0].isdigit():
1489
+ const_value_upper = '_' + const_value_upper
1490
+ if is_java_reserved_word(const_value_upper.lower()):
1491
+ const_value_upper = '_' + const_value_upper
1492
+ const_value = f'{field_type.type_name}.{const_value_upper}'
1455
1493
  elif field_type.type_name == 'String':
1456
1494
  const_value = f'"{const_value}"'
1457
1495
 
@@ -1464,11 +1502,12 @@ class AvroToJava:
1464
1502
  property_def += f"{INDENT}@JsonIgnore\n"
1465
1503
  property_def += f"{INDENT}public {field_type.type_name} get{pascal(field_name)}Value() {{ return {safe_field_name}; }}\n"
1466
1504
  # Generate the getter that returns String (Jackson will use this for serialization)
1505
+ # Use avroSymbol() to get the original Avro symbol name for serialization
1467
1506
  # Use READ_ONLY since this is a const field that doesn't need deserialization
1468
1507
  # Note: Not using @Override because not all discriminated union variants extend a base class
1469
1508
  if self.jackson_annotations:
1470
1509
  property_def += f"{INDENT}@JsonProperty(value=\"{field['name']}\", access=JsonProperty.Access.READ_ONLY)\n"
1471
- property_def += f"{INDENT}public String get{pascal(field_name)}() {{ return {safe_field_name}.name(); }}\n"
1510
+ property_def += f"{INDENT}public String get{pascal(field_name)}() {{ return {safe_field_name}.avroSymbol(); }}\n"
1472
1511
  else:
1473
1512
  property_def += f"{INDENT}public {field_type.type_name} get{pascal(field_name)}() {{ return {safe_field_name}; }}\n"
1474
1513
  else:
@@ -1651,14 +1690,14 @@ class AvroToJava:
1651
1690
  jackson_annotation=self.jackson_annotations
1652
1691
  )
1653
1692
  elif type_kind == "enum":
1654
- # Convert symbols to Java-safe identifiers (same logic as generate_enum)
1693
+ # Convert symbols to Java-safe identifiers in SCREAMING_CASE (same logic as generate_enum)
1655
1694
  raw_symbols = avro_schema.get('symbols', [])
1656
1695
  java_safe_symbols = []
1657
1696
  for symbol in raw_symbols:
1658
- java_symbol = symbol.replace('-', '_').replace('.', '_')
1697
+ java_symbol = symbol.replace('-', '_').replace('.', '_').upper()
1659
1698
  if java_symbol and java_symbol[0].isdigit():
1660
1699
  java_symbol = '_' + java_symbol
1661
- if is_java_reserved_word(java_symbol):
1700
+ if is_java_reserved_word(java_symbol.lower()):
1662
1701
  java_symbol = '_' + java_symbol
1663
1702
  java_safe_symbols.append(java_symbol)
1664
1703
 
@@ -1808,9 +1847,15 @@ class AvroToJava:
1808
1847
  # Generate test value for the field
1809
1848
  if "const" in field and field["const"] is not None:
1810
1849
  const_value = field["const"]
1811
- # For enum types, qualify with the enum type name
1850
+ # For enum types, qualify with the enum type name and convert to SCREAMING_CASE
1812
1851
  if is_enum or (field_type.type_name not in ('String', 'int', 'Integer', 'long', 'Long', 'double', 'Double', 'boolean', 'Boolean')):
1813
- test_value = f'{field_type.type_name}.{const_value}'
1852
+ # Convert enum const value to uppercase to match Java enum constant naming convention
1853
+ const_value_upper = str(const_value).replace('-', '_').replace('.', '_').upper()
1854
+ if const_value_upper and const_value_upper[0].isdigit():
1855
+ const_value_upper = '_' + const_value_upper
1856
+ if is_java_reserved_word(const_value_upper.lower()):
1857
+ const_value_upper = '_' + const_value_upper
1858
+ test_value = f'{field_type.type_name}.{const_value_upper}'
1814
1859
  else:
1815
1860
  test_value = f'"{const_value}"'
1816
1861
  else:
@@ -1896,12 +1941,12 @@ class AvroToJava:
1896
1941
  avro_schema = self.generated_avro_schemas.get(java_type, {})
1897
1942
  symbols = avro_schema.get('symbols', [])
1898
1943
  if symbols:
1899
- # Convert symbol to valid Java identifier (same logic as in generate_enum)
1900
- first_symbol = symbols[0].replace('-', '_').replace('.', '_')
1944
+ # Convert symbol to valid Java identifier in SCREAMING_CASE (same logic as in generate_enum)
1945
+ first_symbol = symbols[0].replace('-', '_').replace('.', '_').upper()
1901
1946
  if first_symbol and first_symbol[0].isdigit():
1902
1947
  first_symbol = '_' + first_symbol
1903
1948
  # Check if the symbol is a Java reserved word and prefix with underscore
1904
- if is_java_reserved_word(first_symbol):
1949
+ if is_java_reserved_word(first_symbol.lower()):
1905
1950
  first_symbol = '_' + first_symbol
1906
1951
  # Use fully qualified name to avoid conflicts with field names
1907
1952
  return f'{java_type}.{first_symbol}'
@@ -2048,7 +2093,16 @@ class AvroToJava:
2048
2093
  groupid = '.'.join(package_elements[:-1]) if len(package_elements) > 1 else package_elements[0]
2049
2094
  artifactid = package_elements[-1]
2050
2095
  with open(pom_path, 'w', encoding='utf-8') as file:
2051
- file.write(POM_CONTENT.format(groupid=groupid, artifactid=artifactid, AVRO_VERSION=AVRO_VERSION, JACKSON_VERSION=JACKSON_VERSION, JDK_VERSION=JDK_VERSION, PACKAGE=self.base_package))
2096
+ file.write(POM_CONTENT.format(
2097
+ groupid=groupid,
2098
+ artifactid=artifactid,
2099
+ AVRO_VERSION=AVRO_VERSION,
2100
+ JACKSON_VERSION=JACKSON_VERSION,
2101
+ JDK_VERSION=JDK_VERSION,
2102
+ JUNIT_VERSION=JUNIT_VERSION,
2103
+ MAVEN_COMPILER_VERSION=MAVEN_COMPILER_VERSION,
2104
+ MAVEN_SUREFIRE_VERSION=MAVEN_SUREFIRE_VERSION,
2105
+ PACKAGE=self.base_package))
2052
2106
  output_dir = os.path.join(
2053
2107
  output_dir, "src/main/java".replace('/', os.sep))
2054
2108
  if not os.path.exists(output_dir):