174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// Copyright (C) 2013 Google Inc.
274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org//
374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// Licensed under the Apache License, Version 2.0 (the "License");
474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// you may not use this file except in compliance with the License.
574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// You may obtain a copy of the License at
674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org//
774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// http://www.apache.org/licenses/LICENSE-2.0
874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org//
974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// Unless required by applicable law or agreed to in writing, software
1074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// distributed under the License is distributed on an "AS IS" BASIS,
1174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// See the License for the specific language governing permissions and
1374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org// limitations under the License.
1474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
1574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include "rule.h"
1674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
17f02f934fdc353f6f4c13e1d282239e1238ab6a2droubert@google.com#include <cassert>
18c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com#include <cstddef>
1974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include <map>
2074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include <string>
2174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include <utility>
2274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
239f47fe3ed525accac995b095d408a825673a2ee1roubert@google.com#include <re2/re2.h>
249f47fe3ed525accac995b095d408a825673a2ee1roubert@google.com
2574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include "address_field_util.h"
269f47fe3ed525accac995b095d408a825673a2ee1roubert@google.com#include "format_element.h"
2774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include "grit.h"
2874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include "messages.h"
2985cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com#include "region_data_constants.h"
3074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org#include "util/json.h"
31ea5e77397b59d94af3591644c3dc23dc6f9ba22eroubert@google.com#include "util/re2ptr.h"
32c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com#include "util/string_split.h"
3374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
3474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgnamespace i18n {
3574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgnamespace addressinput {
3674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
3774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgnamespace {
3874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
3974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgtypedef std::map<std::string, int> NameMessageIdMap;
4074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
41c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com// Used as a separator in a list of items. For example, the list of supported
42c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com// languages can be "de~fr~it".
43c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.comconst char kSeparator = '~';
4474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
4574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgNameMessageIdMap InitAdminAreaMessageIds() {
4674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  NameMessageIdMap message_ids;
4774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
4831a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "area", IDS_LIBADDRESSINPUT_AREA));
4974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
5031a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "county", IDS_LIBADDRESSINPUT_COUNTY));
5174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
5231a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "department", IDS_LIBADDRESSINPUT_DEPARTMENT));
5374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
5431a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "district", IDS_LIBADDRESSINPUT_DISTRICT));
5574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
5631a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "do_si", IDS_LIBADDRESSINPUT_DO_SI));
5774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
5831a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "emirate", IDS_LIBADDRESSINPUT_EMIRATE));
5974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
6031a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "island", IDS_LIBADDRESSINPUT_ISLAND));
6174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
6239fc575f34f8024ae785ec597a3125d8d00ebd0alararennie@google.com      "oblast", IDS_LIBADDRESSINPUT_OBLAST));
6339fc575f34f8024ae785ec597a3125d8d00ebd0alararennie@google.com  message_ids.insert(std::make_pair(
6431a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "parish", IDS_LIBADDRESSINPUT_PARISH));
6574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
6631a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "prefecture", IDS_LIBADDRESSINPUT_PREFECTURE));
6774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
6831a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "province", IDS_LIBADDRESSINPUT_PROVINCE));
6974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
7031a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "state", IDS_LIBADDRESSINPUT_STATE));
7174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  return message_ids;
7274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
7374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
7474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgconst NameMessageIdMap& GetAdminAreaMessageIds() {
7574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  static const NameMessageIdMap kAdminAreaMessageIds(InitAdminAreaMessageIds());
7674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  return kAdminAreaMessageIds;
7774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
7874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
7974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgNameMessageIdMap InitPostalCodeMessageIds() {
8074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  NameMessageIdMap message_ids;
8174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
8231a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "postal", IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL));
8374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  message_ids.insert(std::make_pair(
8431a450a1422a067b3ddd0a47ffd8b33fb5d0e189keghani@google.com      "zip", IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL));
8574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  return message_ids;
8674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
8774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
8874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgconst NameMessageIdMap& GetPostalCodeMessageIds() {
8974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  static const NameMessageIdMap kPostalCodeMessageIds(
9074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org      InitPostalCodeMessageIds());
9174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  return kPostalCodeMessageIds;
9274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
9374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
9474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgint GetMessageIdFromName(const std::string& name,
9574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org                         const NameMessageIdMap& message_ids) {
9674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  NameMessageIdMap::const_iterator it = message_ids.find(name);
9774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  return it != message_ids.end() ? it->second : INVALID_MESSAGE_ID;
9874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
9974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
10059785b737879e688618ce91947ee45438e52b73ddavinci@google.com// Determines whether a given string is a reg-exp or a string. We consider a
10159785b737879e688618ce91947ee45438e52b73ddavinci@google.com// string to be anything that doesn't contain characters with special meanings
10259785b737879e688618ce91947ee45438e52b73ddavinci@google.com// in regular expressions - (, [, \, {, ?. These special characters are all the
10359785b737879e688618ce91947ee45438e52b73ddavinci@google.com// ones that appear in the postal code regular expressions.
10459785b737879e688618ce91947ee45438e52b73ddavinci@google.combool ContainsRegExSpecialCharacters(const std::string& input) {
10559785b737879e688618ce91947ee45438e52b73ddavinci@google.com  return input.find_first_of("([\\{?") != std::string::npos;
10659785b737879e688618ce91947ee45438e52b73ddavinci@google.com}
10759785b737879e688618ce91947ee45438e52b73ddavinci@google.com
10874f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}  // namespace
10974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
11074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgRule::Rule()
111c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    : id_(),
112c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      format_(),
113947ce24396bbb66ec5fcd14a73f85f4e32c3dcc0rouslan@chromium.org      latin_format_(),
114c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      required_(),
115c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      sub_keys_(),
116c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      languages_(),
117c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      postal_code_matcher_(NULL),
11859785b737879e688618ce91947ee45438e52b73ddavinci@google.com      sole_postal_code_(),
11974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org      admin_area_name_message_id_(INVALID_MESSAGE_ID),
120f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org      postal_code_name_message_id_(INVALID_MESSAGE_ID),
121f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org      name_(),
122e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com      latin_name_(),
123e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com      postal_code_example_(),
124e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com      post_service_url_() {}
12574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
12674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgRule::~Rule() {}
12774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
12885cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com// static
12985cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.comconst Rule& Rule::GetDefault() {
13085cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com  // Allocated once and leaked on shutdown.
13185cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com  static Rule* default_rule = NULL;
13285cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com  if (default_rule == NULL) {
13385cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com    default_rule = new Rule;
13485cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com    default_rule->ParseSerializedRule(
13585cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com        RegionDataConstants::GetDefaultRegionData());
13685cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com  }
13785cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com  return *default_rule;
13885cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com}
13985cb27556ac9e6ad518c6f56edc3d8a662423ad1roubert@google.com
14074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgvoid Rule::CopyFrom(const Rule& rule) {
141f02f934fdc353f6f4c13e1d282239e1238ab6a2droubert@google.com  assert(this != &rule);
142c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  id_ = rule.id_;
14374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  format_ = rule.format_;
144947ce24396bbb66ec5fcd14a73f85f4e32c3dcc0rouslan@chromium.org  latin_format_ = rule.latin_format_;
145c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  required_ = rule.required_;
146c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  sub_keys_ = rule.sub_keys_;
147c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  languages_ = rule.languages_;
148c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  postal_code_matcher_.reset(
149c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      rule.postal_code_matcher_ == NULL
150c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com          ? NULL
151c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com          : new RE2ptr(new RE2(rule.postal_code_matcher_->ptr->pattern(),
152c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com                               rule.postal_code_matcher_->ptr->options())));
15359785b737879e688618ce91947ee45438e52b73ddavinci@google.com  sole_postal_code_ = rule.sole_postal_code_;
15474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  admin_area_name_message_id_ = rule.admin_area_name_message_id_;
15574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  postal_code_name_message_id_ = rule.postal_code_name_message_id_;
156f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org  name_ = rule.name_;
157f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org  latin_name_ = rule.latin_name_;
158e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com  postal_code_example_ = rule.postal_code_example_;
159e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com  post_service_url_ = rule.post_service_url_;
16074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
16174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
16274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.orgbool Rule::ParseSerializedRule(const std::string& serialized_rule) {
16374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  Json json;
16474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  if (!json.ParseObject(serialized_rule)) {
16574f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org    return false;
16674f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  }
16741dd744f8493cfa6fc3f7c457cf53995a45e69f9rouslan@chromium.org  ParseJsonRule(json);
16841dd744f8493cfa6fc3f7c457cf53995a45e69f9rouslan@chromium.org  return true;
16941dd744f8493cfa6fc3f7c457cf53995a45e69f9rouslan@chromium.org}
17074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
17141dd744f8493cfa6fc3f7c457cf53995a45e69f9rouslan@chromium.orgvoid Rule::ParseJsonRule(const Json& json) {
172f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  std::string value;
173f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("id", &value)) {
174f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    id_.swap(value);
175c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  }
176c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com
177f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("fmt", &value)) {
178f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    ParseFormatRule(value, &format_);
17974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  }
18074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
181f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("lfmt", &value)) {
182f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    ParseFormatRule(value, &latin_format_);
183947ce24396bbb66ec5fcd14a73f85f4e32c3dcc0rouslan@chromium.org  }
184947ce24396bbb66ec5fcd14a73f85f4e32c3dcc0rouslan@chromium.org
185f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("require", &value)) {
186f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    ParseAddressFieldsRequired(value, &required_);
187c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  }
188c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com
189f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("sub_keys", &value)) {
190f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    SplitString(value, kSeparator, &sub_keys_);
191c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  }
192c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com
193f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("languages", &value)) {
194f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    SplitString(value, kSeparator, &languages_);
195c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  }
196c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com
19759785b737879e688618ce91947ee45438e52b73ddavinci@google.com  sole_postal_code_.clear();
198f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("zip", &value)) {
199c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // The "zip" field in the JSON data is used in two different ways to
200c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // validate the postal code. At the country level, the "zip" field indicates
201c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // a Java compatible regular expression corresponding to all postal codes in
202c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // the country. At other levels, the regular expression indicates the postal
203c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // code prefix expected for addresses in that region.
204c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    //
205c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // In order to make the RE2 object created from the "zip" field useable for
206c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // both these purposes, the pattern string is here prefixed with "^" to
207c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // anchor it at the beginning of the string so that it can be used with
208c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // RE2::PartialMatch() to perform prefix matching or else with
209c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    // RE2::FullMatch() to perform matching against the entire string.
210c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    RE2::Options options;
211c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    options.set_never_capture(true);
212f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    RE2* matcher = new RE2("^(" + value + ")", options);
213c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    if (matcher->ok()) {
214c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      postal_code_matcher_.reset(new RE2ptr(matcher));
215c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    } else {
216c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      postal_code_matcher_.reset(NULL);
217c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com      delete matcher;
218c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com    }
21959785b737879e688618ce91947ee45438e52b73ddavinci@google.com    // If the "zip" field is not a regular expression, then it is the sole
22059785b737879e688618ce91947ee45438e52b73ddavinci@google.com    // postal code for this rule.
221f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    if (!ContainsRegExSpecialCharacters(value)) {
222f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org      sole_postal_code_.swap(value);
22359785b737879e688618ce91947ee45438e52b73ddavinci@google.com    }
224c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com  }
225c86c2bb38da4922d1dc8f5fcc0b535cecfc8745croubert@google.com
226f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("state_name_type", &value)) {
22774f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org    admin_area_name_message_id_ =
228f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org        GetMessageIdFromName(value, GetAdminAreaMessageIds());
22974f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  }
23074f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
231f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("zip_name_type", &value)) {
23274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org    postal_code_name_message_id_ =
233f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org        GetMessageIdFromName(value, GetPostalCodeMessageIds());
23474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org  }
235f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org
236f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("name", &value)) {
237f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    name_.swap(value);
238f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org  }
239f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org
240f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("lname", &value)) {
241f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    latin_name_.swap(value);
242f1be124367e8e74e1a235774914e3d4f970e9444rouslan@chromium.org  }
243e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com
244f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("zipex", &value)) {
245f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    postal_code_example_.swap(value);
246e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com  }
247e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com
248f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org  if (json.GetStringValueForKey("posturl", &value)) {
249f924b7dfea039ad262f25c2d19fb9bd4905b96e8rouslan@chromium.org    post_service_url_.swap(value);
250e66bf12636bf12067bd8b199b8e6c1035315d2aakeghani@google.com  }
25174f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}
25274f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org
25374f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}  // namespace addressinput
25474f7033f5c34dcca3d63d2aad0073bb50c5d9e22rouslan@chromium.org}  // namespace i18n
255