BaldDemian opened a new pull request, #3814:
URL: https://github.com/apache/fory/pull/3814

   ## Why?
   
   The C++ compiler can emit union metadata macros that fail to compile when a 
union case payload type contains a C++ template comma, e.g. 
`std::unordered_map<K, V>`.
   
   There are two affected paths:
   
   - `FORY_UNION(...)` for unions with at most 16 cases.
   - `FORY_UNION_IDS(...)` plus `FORY_UNION_CASE(...)` for larger unions.
   
   Example IDL:
   
   ```
   package probe.cpp_macro_fory_union;
   
   union SmallChoice {
     map<string, any> by_name = 1;
     string name = 2;
   }
   ```
   
   Generated C++ code:
   
   ```c++
   FORY_UNION(probe::cpp_macro_fory_union::SmallChoice,
     (by_name, std::unordered_map<std::string, std::any>, 
fory::F(1).map(fory::T::string(), fory::FieldNodeSpec{})),
     (name, std::string, fory::F(2))
   );
   ```
   
   Observed compile error:
   
   ```text
   /home/hpy/fory/cpp/fory/serialization/union_serializer.h:1203:18: error: 
'FORY_UNION_CASE_META_fory' has not been declared
   
/tmp/fory_cpp_macro_pr_wql7zo9p/generated/probe_cpp_macro_fory_union.h:140:4: 
error: 'by_name' was not declared in this scope
   
/tmp/fory_cpp_macro_pr_wql7zo9p/generated/probe_cpp_macro_fory_union.h:140:54: 
error: expected primary-expression before ',' token
   /home/hpy/fory/cpp/fory/serialization/union_serializer.h:1192:18: error: 
'FORY_UNION_CASE_TYPE_fory' was not declared in this scope; did you mean 
'FORY_UNION_CASE_TYPE_2'?
   ```
   
   **Root cause**:
   
   The generator passed **raw** C++ type names into `FORY_UNION` case tuples. 
   `FORY_UNION` rendered each case as `(case_name, case_type, meta)`:
   
   
https://github.com/apache/fory/blob/23aa3f98ee56687c555c681a488a69d8cfbb5832/compiler/fory_compiler/generators/cpp.py#L1203-L1221
   
   This is unsafe for template types such as `std::unordered_map<std::string, 
std::any>`.
   
   C++ macro preprocessing happens before the compiler understands that the 
comma inside `<K, V>` belongs to a template argument list. The preprocessor 
treats that comma as a macro argument separator.
   
   `FORY_UNION` expects each case tuple to have either two entries `(name, 
meta)` or three entries `(name, type, meta)`:
   
   
https://github.com/apache/fory/blob/23aa3f98ee56687c555c681a488a69d8cfbb5832/cpp/fory/serialization/union_serializer.h#L1179-L1207
   
   When the generated tuple contains:
   
   ```cpp
   (by_name, std::unordered_map<std::string, std::any>, meta)
   ```
   
   the preprocessor sees more entries than intended because of the comma in 
`std::unordered_map<std::string, std::any>`. 
   That breaks tuple-size selection and causes invalid macro names such as 
`FORY_UNION_CASE_META_fory` or `FORY_UNION_CASE_TYPE_fory`.
   
   
   ## What does this PR do?
   
   Fix this by generating a union-scoped type alias for case payload types 
whose rendered C++ type
   contains a comma, and use that alias in `FORY_UNION` and `FORY_UNION_CASE` 
metadata.
   
   The generated alias name is derived from the union case name using the 
pattern:
   
   `ForyCase` + PascalCase(case_name) + `Type`.
   
   e.g.
   
   ```cpp
   class SmallChoice final {
    public:
     using ForyCaseByNameType = std::unordered_map<std::string, std::any>;
     ...
   };
   
   FORY_UNION(probe::cpp_macro_fory_union::SmallChoice,
     (by_name, probe::cpp_macro_fory_union::SmallChoice::ForyCaseByNameType, 
fory::F(1).map(...)),
     (name, std::string, fory::F(2))
   );
   ```
   
   The macro now receives `SmallChoice::ForyCaseByNameType`, which contains no 
template comma and can be parsed safely by the preprocessor.
   
   Note: I will handle naming collisions universally in a new PR.
   
   ## Related issues
   
   N/A.
   
   ## AI Contribution Checklist
   
   - [X] Substantial AI assistance was used in this PR: `no`
   
   ## Does this PR introduce any user-facing change?
   
   N/A.
   
   ## Benchmark
   
   N/A.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to