@@ -82,7 +82,9 @@ The following table shows how data is represented in JSON files.
8282 <td>string</td>
8383 <td><code>"FOO_BAR"</code></td>
8484 <td>The name of the enum value as specified in proto is used. Parsers
85- accept both enum names and integer values.
85+ accept both enum names and integer values. See
86+ <a href="#enum-aliasing">Enum Aliasing</a> for details on enums with
87+ aliases.
8688 </td>
8789 </tr>
8890 <tr>
@@ -359,6 +361,85 @@ JSON when prioritizing interoperability, including:
359361 documentation recommends using a JSON string instead of a number when
360362 precision beyond 2** 53 is desired.
361363
364+ ## Enum Aliasing {#enum-aliasing}
365+
366+ When an enum definition has ` option allow_aliasing = true; ` , multiple enum
367+ constant names can map to the same numeric value.
368+
369+ ### Serialization Behavior
370+
371+ Serializers ** must** print the first listed name in the enum definition for a
372+ given numeric value.
373+
374+ For example, given:
375+
376+ ``` proto
377+ enum MyEnum {
378+ option allow_alias = true;
379+ UNKNOWN = 0;
380+ OLD_NAME = 1;
381+ NEW_NAME = 1;
382+ }
383+ ```
384+
385+ If the value is ` 1 ` , the serializer will output ` "OLD_NAME" ` .
386+
387+ ### Parsing Behavior
388+
389+ Parsers ** must** accept any of the names defined for that numeric value. In the
390+ example above, the parser will accept both ` "OLD_NAME" ` and ` "NEW_NAME" ` as
391+ mapping to value ` 1 ` .
392+
393+ ### Safe Renaming Strategy {#safe-renaming}
394+
395+ This behavior enables a safe, multi-step migration path for renaming enum values
396+ in a distributed system:
397+
398+ 1 . ** Add the new name as an alias:** Add the new name below the old name,
399+ mapping to the same value.
400+
401+ ``` proto
402+ enum MyEnum {
403+ option allow_aliasing = true;
404+ UNKNOWN = 0;
405+ OLD_NAME = 1;
406+ NEW_NAME = 1; // New name added as alias
407+ }
408+ ```
409+
410+ 2. **Deploy the schema:** Deploy this schema to all systems. At this point, all
411+ parsers will recognize both `OLD_NAME` and `NEW_NAME`, but all serializers
412+ will still emit `OLD_NAME` (since it is listed first).
413+
414+ 3. **Swap the order:** Swap the order of the aliases in the proto file.
415+
416+ ```proto
417+ enum MyEnum {
418+ option allow_aliasing = true;
419+ UNKNOWN = 0;
420+ NEW_NAME = 1; // New name is now first
421+ OLD_NAME = 1;
422+ }
423+ ```
424+
425+ 4. **Deploy the schema:** Deploy this updated schema. Now, serializers will
426+ begin emitting `NEW_NAME`. Parsers will still accept both names, ensuring
427+ that any systems still running the previous version of the schema can safely
428+ parse the new name.
429+
430+ 5. **Remove the old name:** Once all systems have been updated and you are sure
431+ no old serialized data remains that needs to be parsed by a system that
432+ might be rolled back, you can safely remove the old name.
433+
434+ ```proto
435+ enum MyEnum {
436+ UNKNOWN = 0;
437+ NEW_NAME = 1;
438+ }
439+ ```
440+
441+ This semantic also matches TextProto for the same reason.
442+
362443## Any {#any}
363444
364445### Normal messages {#any-normal-messages}
0 commit comments