Skip to content

[messages_builder] Support ICU single-quote escaping in Parser - #1122

Open
mosuem wants to merge 1 commit into
mainfrom
icuSingleQuoteEscapes
Open

mosuem wants to merge 1 commit into
mainfrom
icuSingleQuoteEscapes

Conversation

@mosuem

@mosuem mosuem commented Oct 30, 2026

Copy link
Copy Markdown
Member

Note

This PR was generated by an AI coding agent (Jetski) on behalf of @mosuem.

Implements standard ICU 4.8+ (MessagePattern ApostropheMode.DOUBLE_OPTIONAL) single-quote escaping in pkgs/messages_builder/lib/message_parser/icu_message_parser.dart:

  • '' always collapses to a single literal '.
  • ' immediately preceding { or } starts quoted literal text until the matching closing ' (with '' inside quoted text producing a literal '), throwing L10nParserException if unclosed at end of input.
  • Lone ' characters not preceding ', {, or } (e.g. "It's {name}", "L'article") remain literal '.
  • Rejects stray unescaped closing braces (}) left over after parsing instead of silently truncating the rest of the message.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request updates the message parser to align with standard ICU message formatting rules regarding single-quote escaping. By replacing the previous regex-based approach with a more robust manual lexing logic, the parser now correctly handles literal quotes, escaped braces, and provides better error reporting for malformed message strings.

Highlights

  • ICU Single-Quote Escaping: Implemented standard ICU 4.8+ ApostropheMode.DOUBLE_OPTIONAL support, allowing proper handling of single quotes, doubled single quotes, and quoted braces.
  • Error Handling: Added strict validation to reject stray unescaped closing braces and unclosed quoted sections, throwing descriptive L10nParserExceptions.
  • Testing: Added comprehensive test suite covering various escaping scenarios, including nested structures and edge cases.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@github-actions

Copy link
Copy Markdown

PR Health

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?

This check can be disabled by tagging the PR with skip-breaking-check.

Coverage ✔️
File Coverage

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check (for example, for non-user-visible changes when the package version is already at -wip).

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

This check can be disabled by tagging the PR with skip-license-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Unused Dependencies ✔️
Package Status
None No packages found to check.

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for ICU single-quote escaping (specifically ApostropheMode.DOUBLE_OPTIONAL) in the Parser class of messages_builder. It updates the lexing logic in icu_message_parser.dart to handle doubled single quotes and quoted braces/placeholders, and adds validation to throw an exception on unexpected trailing tokens. Comprehensive unit tests covering various escaping scenarios and error cases have also been added. There are no review comments, so I have no feedback to provide.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant