Convertisseur Protobuf vers Java
Collez un schéma .proto. Récupérez des classes Java simples à déposer dans un projet — champs publics, pas de getters, faciles à adapter.
Entrée (schéma .proto)
Sortie (Java)
Ce que fait cet outil
Vous avez un schéma Protocol Buffers et un service Java qui consomme ces messages — peut-être via gRPC, peut-être via JSON sur HTTP. Lancer le protoc officiel avec le plugin Java vous donne des classes générées en pattern Builder, parfaites pour la prod mais lourdes pour esquisser, prototyper ou mapper du JSON à la main sur un POJO. Ce convertisseur produit des classes Java simples — champs publics, valeurs par défaut sensées, une classe par message, types séparés pour les enums.
Le mapping de types suit ce qu'on voit dans du Java écrit à la main : string → String, bool → boolean, int32/sint32/sfixed32 → int, int64/sint64/sfixed64 → long, double → double, float → float, bytes → byte[]. Java n'a pas de types numériques non signés, donc uint32/fixed32 tombent en int et uint64/fixed64 tombent en long — ça va pour la plupart des cas ; si vous avez vraiment besoin du bit de poids fort, utilisez Integer.toUnsignedLong à la frontière. repeated T devient List<T>, map<K, V> devient Map<K, V>, les deux depuis java.util.
Les noms de champs passent de snake_case (convention Protobuf) à camelCase (convention Java) — comme le ferait protoc, et comme l'utilise le mapping JSON proto3. Les enums deviennent des types public enum de premier niveau avec la valeur entière du fil conservée dans un champ final, ce qui permet le round-trip via du code généré par protoc si vous basculez un jour. Les messages imbriqués sont aplatis en classes de premier niveau pour que chacun puisse partir dans son propre fichier quand vous découpez la sortie. Tout tourne dans votre navigateur — votre schéma ne quitte pas la page.
Comment l'utiliser
Trois étapes. La sortie est prête à déposer dans un projet Java.
Collez votre schéma .proto
Déposez le schéma dans l'éditeur de gauche. syntax = "proto3"; en tête est OK mais optionnel. Le parser gère les blocs message imbriqués, les déclarations enum, oneof, map<K, V> et les options de champs. Les directives import sont reconnues mais ignorées — collez les types importés inline si vous en avez besoin.
La conversion des noms de champs est automatique : order_id dans le .proto devient orderId en Java. Les noms de messages et d'enums restent tels quels (déjà en PascalCase).
Lisez la sortie
À droite : un seul bloc .java avec tous les enums d'abord, puis toutes les classes dans l'ordre de déclaration. Chaque classe a des champs publics avec des valeurs par défaut pour les primitifs (0, 0.0, false, ""), et les types référence (List, Map, refs de messages) restent à null jusqu'à ce que vous les remplissiez. Les imports java.util.List et java.util.Map ne sont ajoutés que si le schéma en a besoin.
Déposez dans votre projet
Copiez chaque classe dans son propre fichier .java (Java exige une classe publique par fichier). Ajoutez une déclaration package, puis branchez les classes à votre désérialiseur JSON préféré — Jackson prend les champs publics par défaut, et le mapping JSON proto3 utilise camelCase, donc les noms de champs collent déjà. Si vous préférez des getters/setters, le refactor "Encapsulate Fields" d'IntelliJ le fait en une frappe.
Quand ça fait vraiment gagner du temps
Esquisser un client Java pour un service gRPC
Vous bricolez un client Java contre un backend gRPC existant — peut-être un service Spring Boot, peut-être un Quarkus — et vous ne voulez pas encore mettre en place le plugin protoc Maven ou Gradle complet. Collez le schéma, déposez les classes dans src/main/java/dto, désérialisez la réponse JSON avec Jackson, livrez le proto.
Écrire à la main des DTOs qui matchent un proto
Votre équipe utilise Protobuf comme source de vérité sur le fil, mais le service Java consommateur n'a besoin que de trois ou quatre champs et vous ne voulez pas d'une dépendance Message/Builder. Collez le schéma, supprimez les champs dont vous n'avez pas besoin, vous avez un DTO simple qui compile en standalone.
Relire un changement d'API Protobuf
Un coéquipier backend a ajouté des champs à un message. Vous voulez voir comment ça impacte le POJO Java sans lancer le build. Collez le nouveau .proto, faites un diff de la sortie Java contre vos classes actuelles, laissez un commentaire de revue ciblé.
Recouper la sortie générée par protoc
Votre build utilise le plugin Java officiel de protoc, qui produit des classes en pattern Builder. Collez le schéma ici pour avoir une référence propre de ce à quoi ressemble du Java simple, utile pour la doc, l'onboarding ou pour les coéquipiers Kotlin qui préfèrent les data classes.
Questions fréquentes
Mon schéma part-il quelque part ?
Non. Le parser et l'émetteur Java tournent entièrement dans votre navigateur en JavaScript. Ouvrez les DevTools et regardez l'onglet Network pendant que vous collez — zéro requête. Pratique quand votre schéma contient des chemins de package internes, des noms de types ou n'importe quoi que vous ne voudriez pas envoyer à un service tiers.
Pourquoi des champs publics et pas des getters/setters ?
Deux raisons. D'abord, la sortie est faite pour être un point de départ que vous adaptez — les champs publics, c'est la plus petite chose qui compile, et vous pouvez toujours lancer "Encapsulate Fields" dans votre IDE. Ensuite, le consommateur le plus courant, c'est la désérialisation Jackson, qui marche d'office sur les champs publics. Si vous avez besoin d'un record, d'un type immuable ou d'une classe Lombok @Data, collez la sortie et refactorisez.
Comment uint32 et uint64 sont-ils gérés ?
Java n'a pas de types entiers non signés, donc uint32/fixed32 mappent vers int et uint64/fixed64 vers long. Pour les valeurs qui rentrent dans la plage signée, ça marche ; pour les valeurs au-dessus de Integer.MAX_VALUE ou Long.MAX_VALUE, vous verrez des nombres négatifs. La parade standard, c'est Integer.toUnsignedLong(x) à la frontière, ou utiliser les helpers arithmétiques de java.lang.Long — voir la doc API Java 21 pour les helpers non signés.
Pourquoi les champs int64 sont-ils juste long, pas String ?
TypeScript et JSON ont un plafond de précision à 53 bits, donc la spec JSON proto3 encode les entiers 64 bits en chaînes pour préserver la précision. Le long de Java est un vrai entier signé 64 bits sans perte de précision, donc on garde le type Java en long. Si vous désérialisez du JSON où le serveur a déjà encodé l'int64 en chaîne, configurez Jackson avec @JsonFormat ou un désérialiseur custom ; le type sous-jacent n'a pas besoin de changer.
Comment gère-t-il les messages imbriqués ?
Chaque message imbriqué est aplati en une classe de premier niveau. La convention Java, c'est une classe publique par fichier, donc les types plats de premier niveau sont plus faciles à découper quand vous copiez chaque classe dans son propre .java. Si vous préférez avoir des static inner classes (le style que protoc émet), collez la sortie et déplacez les classes imbriquées à l'intérieur de leur parent — les références aux champs utilisent déjà le nom court et seront résolues une fois dans le même scope.
Les champs sont-ils marqués comme optionnels ?
Non — les champs proto3 ont toujours un défaut dans le format du fil, donc les champs primitifs sont initialisés à leur valeur zéro Java (0, 0.0, false, ""). Les types référence (List, Map, messages imbriqués, byte[]) démarrent à null ; pensez à les initialiser avant d'ajouter des éléments. Si vous voulez des wrappers Optional<T> explicites, c'est une étape manuelle.
Gère-t-il oneof ?
Chaque champ de oneof est émis comme un champ de classe normal. La sortie n'impose pas la contrainte "exactement un" qu'implique oneof — pour ça, il faudrait une hiérarchie de types scellée ou un check à l'exécution, deux choses qui ne rentrent pas dans un POJO simple. Si vous voulez une modélisation plus stricte, prenez la sortie et convertissez les champs du oneof en sealed interface avec un record par cas.
Puis-je utiliser ces classes avec le runtime officiel protobuf-java ?
Pas directement — le runtime officiel attend des classes générées par protoc avec Builder, parseFrom et le reste du contrat com.google.protobuf.MessageOrBuilder. Les classes de cet outil sont des POJOs simples, prévus pour la sérialisation JSON (Jackson, Gson, Moshi). Pour le format binaire du fil, vous voulez toujours le codegen officiel — voir le tutoriel Java pour la mise en place.
Outils associés
Si vous travaillez avec Protobuf, JSON et Java, ces outils vont bien ensemble :