• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <google/protobuf/util/field_mask_util.h>
32 
33 #include <algorithm>
34 
35 #include <google/protobuf/stubs/logging.h>
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/field_mask.pb.h>
38 #include <google/protobuf/test_util.h>
39 #include <google/protobuf/unittest.pb.h>
40 #include <gtest/gtest.h>
41 
42 namespace google {
43 namespace protobuf {
44 namespace util {
45 
46 class SnakeCaseCamelCaseTest : public ::testing::Test {
47  protected:
SnakeCaseToCamelCase(const std::string & input)48   string SnakeCaseToCamelCase(const std::string& input) {
49     std::string output;
50     if (FieldMaskUtil::SnakeCaseToCamelCase(input, &output)) {
51       return output;
52     } else {
53       return "#FAIL#";
54     }
55   }
56 
CamelCaseToSnakeCase(const std::string & input)57   string CamelCaseToSnakeCase(const std::string& input) {
58     std::string output;
59     if (FieldMaskUtil::CamelCaseToSnakeCase(input, &output)) {
60       return output;
61     } else {
62       return "#FAIL#";
63     }
64   }
65 };
66 
67 namespace {
68 
TEST_F(SnakeCaseCamelCaseTest,SnakeToCamel)69 TEST_F(SnakeCaseCamelCaseTest, SnakeToCamel) {
70   EXPECT_EQ("fooBar", SnakeCaseToCamelCase("foo_bar"));
71   EXPECT_EQ("FooBar", SnakeCaseToCamelCase("_foo_bar"));
72   EXPECT_EQ("foo3Bar", SnakeCaseToCamelCase("foo3_bar"));
73   // No uppercase letter is allowed.
74   EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("Foo"));
75   // Any character after a "_" must be a lowercase letter.
76   //   1. "_" cannot be followed by another "_".
77   //   2. "_" cannot be followed by a digit.
78   //   3. "_" cannot appear as the last character.
79   EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo__bar"));
80   EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_3bar"));
81   EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_bar_"));
82 }
83 
TEST_F(SnakeCaseCamelCaseTest,CamelToSnake)84 TEST_F(SnakeCaseCamelCaseTest, CamelToSnake) {
85   EXPECT_EQ("foo_bar", CamelCaseToSnakeCase("fooBar"));
86   EXPECT_EQ("_foo_bar", CamelCaseToSnakeCase("FooBar"));
87   EXPECT_EQ("foo3_bar", CamelCaseToSnakeCase("foo3Bar"));
88   // "_"s are not allowed.
89   EXPECT_EQ("#FAIL#", CamelCaseToSnakeCase("foo_bar"));
90 }
91 
TEST_F(SnakeCaseCamelCaseTest,RoundTripTest)92 TEST_F(SnakeCaseCamelCaseTest, RoundTripTest) {
93   // Enumerates all possible snake_case names and test that converting it to
94   // camelCase and then to snake_case again will yield the original name.
95   std::string name = "___abc123";
96   std::sort(name.begin(), name.end());
97   do {
98     std::string camelName = SnakeCaseToCamelCase(name);
99     if (camelName != "#FAIL#") {
100       EXPECT_EQ(name, CamelCaseToSnakeCase(camelName));
101     }
102   } while (std::next_permutation(name.begin(), name.end()));
103 
104   // Enumerates all possible camelCase names and test that converting it to
105   // snake_case and then to camelCase again will yield the original name.
106   name = "abcABC123";
107   std::sort(name.begin(), name.end());
108   do {
109     std::string camelName = CamelCaseToSnakeCase(name);
110     if (camelName != "#FAIL#") {
111       EXPECT_EQ(name, SnakeCaseToCamelCase(camelName));
112     }
113   } while (std::next_permutation(name.begin(), name.end()));
114 }
115 
116 using google::protobuf::FieldMask;
117 using protobuf_unittest::NestedTestAllTypes;
118 using protobuf_unittest::TestAllTypes;
119 using protobuf_unittest::TestRequired;
120 using protobuf_unittest::TestRequiredMessage;
121 
TEST(FieldMaskUtilTest,StringFormat)122 TEST(FieldMaskUtilTest, StringFormat) {
123   FieldMask mask;
124   EXPECT_EQ("", FieldMaskUtil::ToString(mask));
125   mask.add_paths("foo_bar");
126   EXPECT_EQ("foo_bar", FieldMaskUtil::ToString(mask));
127   mask.add_paths("baz_quz");
128   EXPECT_EQ("foo_bar,baz_quz", FieldMaskUtil::ToString(mask));
129 
130   FieldMaskUtil::FromString("", &mask);
131   EXPECT_EQ(0, mask.paths_size());
132   FieldMaskUtil::FromString("fooBar", &mask);
133   EXPECT_EQ(1, mask.paths_size());
134   EXPECT_EQ("fooBar", mask.paths(0));
135   FieldMaskUtil::FromString("fooBar,bazQuz", &mask);
136   EXPECT_EQ(2, mask.paths_size());
137   EXPECT_EQ("fooBar", mask.paths(0));
138   EXPECT_EQ("bazQuz", mask.paths(1));
139 }
140 
TEST(FieldMaskUtilTest,JsonStringFormat)141 TEST(FieldMaskUtilTest, JsonStringFormat) {
142   FieldMask mask;
143   std::string value;
144   EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
145   EXPECT_EQ("", value);
146   mask.add_paths("foo_bar");
147   EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
148   EXPECT_EQ("fooBar", value);
149   mask.add_paths("bar_quz");
150   EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
151   EXPECT_EQ("fooBar,barQuz", value);
152 
153   FieldMaskUtil::FromJsonString("", &mask);
154   EXPECT_EQ(0, mask.paths_size());
155   FieldMaskUtil::FromJsonString("fooBar", &mask);
156   EXPECT_EQ(1, mask.paths_size());
157   EXPECT_EQ("foo_bar", mask.paths(0));
158   FieldMaskUtil::FromJsonString("fooBar,bazQuz", &mask);
159   EXPECT_EQ(2, mask.paths_size());
160   EXPECT_EQ("foo_bar", mask.paths(0));
161   EXPECT_EQ("baz_quz", mask.paths(1));
162 }
163 
TEST(FieldMaskUtilTest,GetFieldDescriptors)164 TEST(FieldMaskUtilTest, GetFieldDescriptors) {
165   std::vector<const FieldDescriptor*> field_descriptors;
166   EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(
167       TestAllTypes::descriptor(), "optional_int32", &field_descriptors));
168   EXPECT_EQ(1, field_descriptors.size());
169   EXPECT_EQ("optional_int32", field_descriptors[0]->name());
170   EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
171       TestAllTypes::descriptor(), "optional_nonexist", nullptr));
172   EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(TestAllTypes::descriptor(),
173                                                  "optional_nested_message.bb",
174                                                  &field_descriptors));
175   EXPECT_EQ(2, field_descriptors.size());
176   EXPECT_EQ("optional_nested_message", field_descriptors[0]->name());
177   EXPECT_EQ("bb", field_descriptors[1]->name());
178   EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
179       TestAllTypes::descriptor(), "optional_nested_message.nonexist", nullptr));
180   // FieldMask cannot be used to specify sub-fields of a repeated message.
181   EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
182       TestAllTypes::descriptor(), "repeated_nested_message.bb", nullptr));
183 }
184 
TEST(FieldMaskUtilTest,TestIsVaildPath)185 TEST(FieldMaskUtilTest, TestIsVaildPath) {
186   EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
187   EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
188   EXPECT_TRUE(
189       FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
190   EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
191       "optional_nested_message.nonexist"));
192   // FieldMask cannot be used to specify sub-fields of a repeated message.
193   EXPECT_FALSE(
194       FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
195 }
196 
TEST(FieldMaskUtilTest,TestIsValidFieldMask)197 TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
198   FieldMask mask;
199   FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
200   EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
201 
202   FieldMaskUtil::FromString(
203       "optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
204   EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
205 }
206 
TEST(FieldMaskUtilTest,TestGetFieldMaskForAllFields)207 TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
208   FieldMask mask;
209   mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>();
210   EXPECT_EQ(1, mask.paths_size());
211   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
212 
213   mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>();
214   EXPECT_EQ(75, mask.paths_size());
215   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
216   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
217   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));
218   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint64", mask));
219   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint32", mask));
220   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint64", mask));
221   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
222   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
223   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
224   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
225   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_float", mask));
226   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_double", mask));
227   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bool", mask));
228   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_string", mask));
229   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bytes", mask));
230   EXPECT_TRUE(
231       FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
232   EXPECT_TRUE(
233       FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
234   EXPECT_TRUE(
235       FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
236   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
237   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
238   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
239   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int32", mask));
240   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int64", mask));
241   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint32", mask));
242   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint64", mask));
243   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint32", mask));
244   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint64", mask));
245   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
246   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
247   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
248   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
249   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_float", mask));
250   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_double", mask));
251   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bool", mask));
252   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_string", mask));
253   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bytes", mask));
254   EXPECT_TRUE(
255       FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
256   EXPECT_TRUE(
257       FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
258   EXPECT_TRUE(
259       FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
260   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
261   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
262   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
263 }
264 
TEST(FieldMaskUtilTest,TestToCanonicalForm)265 TEST(FieldMaskUtilTest, TestToCanonicalForm) {
266   FieldMask in, out;
267   // Paths will be sorted.
268   FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
269   FieldMaskUtil::ToCanonicalForm(in, &out);
270   EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
271   // Duplicated paths will be removed.
272   FieldMaskUtil::FromString("foo,bar,foo", &in);
273   FieldMaskUtil::ToCanonicalForm(in, &out);
274   EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
275   // Sub-paths of other paths will be removed.
276   FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
277   FieldMaskUtil::ToCanonicalForm(in, &out);
278   EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
279 
280   // Test more deeply nested cases.
281   FieldMaskUtil::FromString(
282       "foo.bar.baz1,"
283       "foo.bar.baz2.quz,"
284       "foo.bar.baz2",
285       &in);
286   FieldMaskUtil::ToCanonicalForm(in, &out);
287   EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
288   FieldMaskUtil::FromString(
289       "foo.bar.baz1,"
290       "foo.bar.baz2,"
291       "foo.bar.baz2.quz",
292       &in);
293   FieldMaskUtil::ToCanonicalForm(in, &out);
294   EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
295   FieldMaskUtil::FromString(
296       "foo.bar.baz1,"
297       "foo.bar.baz2,"
298       "foo.bar.baz2.quz,"
299       "foo.bar",
300       &in);
301   FieldMaskUtil::ToCanonicalForm(in, &out);
302   EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
303   FieldMaskUtil::FromString(
304       "foo.bar.baz1,"
305       "foo.bar.baz2,"
306       "foo.bar.baz2.quz,"
307       "foo",
308       &in);
309   FieldMaskUtil::ToCanonicalForm(in, &out);
310   EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
311 }
312 
TEST(FieldMaskUtilTest,TestUnion)313 TEST(FieldMaskUtilTest, TestUnion) {
314   FieldMask mask1, mask2, out;
315   // Test cases without overlapping.
316   FieldMaskUtil::FromString("foo,baz", &mask1);
317   FieldMaskUtil::FromString("bar,quz", &mask2);
318   FieldMaskUtil::Union(mask1, mask2, &out);
319   EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
320   // Overlap with duplicated paths.
321   FieldMaskUtil::FromString("foo,baz.bb", &mask1);
322   FieldMaskUtil::FromString("baz.bb,quz", &mask2);
323   FieldMaskUtil::Union(mask1, mask2, &out);
324   EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
325   // Overlap with paths covering some other paths.
326   FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
327   FieldMaskUtil::FromString("foo.bar,bar", &mask2);
328   FieldMaskUtil::Union(mask1, mask2, &out);
329   EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
330 }
331 
TEST(FieldMaskUtilTest,TestIntersect)332 TEST(FieldMaskUtilTest, TestIntersect) {
333   FieldMask mask1, mask2, out;
334   // Test cases without overlapping.
335   FieldMaskUtil::FromString("foo,baz", &mask1);
336   FieldMaskUtil::FromString("bar,quz", &mask2);
337   FieldMaskUtil::Intersect(mask1, mask2, &out);
338   EXPECT_EQ("", FieldMaskUtil::ToString(out));
339   // Overlap with duplicated paths.
340   FieldMaskUtil::FromString("foo,baz.bb", &mask1);
341   FieldMaskUtil::FromString("baz.bb,quz", &mask2);
342   FieldMaskUtil::Intersect(mask1, mask2, &out);
343   EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
344   // Overlap with paths covering some other paths.
345   FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
346   FieldMaskUtil::FromString("foo.bar,bar", &mask2);
347   FieldMaskUtil::Intersect(mask1, mask2, &out);
348   EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
349 }
350 
TEST(FieldMaskUtilTest,TestSubtract)351 TEST(FieldMaskUtilTest, TestSubtract) {
352   FieldMask mask1, mask2, out;
353   // Normal case.
354   FieldMaskUtil::FromString(
355       "optional_int32,optional_uint64,optional_nested_message,optional_foreign_"
356       "message,repeated_int32,repeated_foreign_message,repeated_nested_message."
357       "bb",
358       &mask1);
359 
360   FieldMaskUtil::FromString(
361       "optional_int32,optional_nested_message.bb,optional_foreign_message.c,"
362       "repeated_int32,repeated_nested_message.bb,repeated_foreign_message.f,"
363       "repeated_foreign_message.d,repeated_nested_message.bb,repeated_uint32",
364       &mask2);
365 
366   FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
367   EXPECT_EQ(
368       "optional_foreign_message.d,optional_uint64,repeated_foreign_message.c",
369       FieldMaskUtil::ToString(out));
370 
371   // mask1 is empty.
372   FieldMaskUtil::FromString("", &mask1);
373   FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
374   EXPECT_EQ("", FieldMaskUtil::ToString(out));
375 
376   // mask1 is "optional_nested_message" and mask2 is
377   // "optional_nested_message.nonexist_field".
378   FieldMaskUtil::FromString("optional_nested_message", &mask1);
379   FieldMaskUtil::FromString("optional_nested_message.nonexist_field", &mask2);
380   FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
381   EXPECT_EQ("optional_nested_message", FieldMaskUtil::ToString(out));
382 
383   // mask1 is "optional_nested_message" and mask2 is
384   // "optional_nested_message".
385   FieldMaskUtil::FromString("optional_nested_message", &mask1);
386   FieldMaskUtil::FromString("optional_nested_message", &mask2);
387   FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
388   EXPECT_EQ("", FieldMaskUtil::ToString(out));
389 
390   // Regression test for b/72727550
391   FieldMaskUtil::FromString("optional_foreign_message.c", &mask1);
392   FieldMaskUtil::FromString("optional_foreign_message,optional_nested_message",
393                             &mask2);
394   FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
395   EXPECT_EQ("", FieldMaskUtil::ToString(out));
396 }
397 
TEST(FieldMaskUtilTest,TestIspathInFieldMask)398 TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
399   FieldMask mask;
400   FieldMaskUtil::FromString("foo.bar", &mask);
401   EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("", mask));
402   EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo", mask));
403   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar", mask));
404   EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar.baz", mask));
405   EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo.bar0.baz", mask));
406 }
407 
TEST(FieldMaskUtilTest,MergeMessage)408 TEST(FieldMaskUtilTest, MergeMessage) {
409   TestAllTypes src, dst;
410   TestUtil::SetAllFields(&src);
411   FieldMaskUtil::MergeOptions options;
412 
413 #define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name)           \
414   {                                                          \
415     TestAllTypes tmp;                                        \
416     tmp.set_##field_name(src.field_name());                  \
417     FieldMask mask;                                          \
418     mask.add_paths(#field_name);                             \
419     dst.Clear();                                             \
420     FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
421     EXPECT_EQ(tmp.DebugString(), dst.DebugString());         \
422     src.clear_##field_name();                                \
423     tmp.clear_##field_name();                                \
424     FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
425     EXPECT_EQ(tmp.DebugString(), dst.DebugString());         \
426   }
427   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
428   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
429   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
430   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
431   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
432   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
433   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
434   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
435   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
436   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
437   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
438   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
439   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
440   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
441   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
442   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
443   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
444   TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
445 #undef TEST_MERGE_ONE_PRIMITIVE_FIELD
446 
447 #define TEST_MERGE_ONE_FIELD(field_name)                     \
448   {                                                          \
449     TestAllTypes tmp;                                        \
450     *tmp.mutable_##field_name() = src.field_name();          \
451     FieldMask mask;                                          \
452     mask.add_paths(#field_name);                             \
453     dst.Clear();                                             \
454     FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
455     EXPECT_EQ(tmp.DebugString(), dst.DebugString());         \
456   }
457   TEST_MERGE_ONE_FIELD(optional_nested_message)
458   TEST_MERGE_ONE_FIELD(optional_foreign_message)
459   TEST_MERGE_ONE_FIELD(optional_import_message)
460 
461   TEST_MERGE_ONE_FIELD(repeated_int32)
462   TEST_MERGE_ONE_FIELD(repeated_int64)
463   TEST_MERGE_ONE_FIELD(repeated_uint32)
464   TEST_MERGE_ONE_FIELD(repeated_uint64)
465   TEST_MERGE_ONE_FIELD(repeated_sint32)
466   TEST_MERGE_ONE_FIELD(repeated_sint64)
467   TEST_MERGE_ONE_FIELD(repeated_fixed32)
468   TEST_MERGE_ONE_FIELD(repeated_fixed64)
469   TEST_MERGE_ONE_FIELD(repeated_sfixed32)
470   TEST_MERGE_ONE_FIELD(repeated_sfixed64)
471   TEST_MERGE_ONE_FIELD(repeated_float)
472   TEST_MERGE_ONE_FIELD(repeated_double)
473   TEST_MERGE_ONE_FIELD(repeated_bool)
474   TEST_MERGE_ONE_FIELD(repeated_string)
475   TEST_MERGE_ONE_FIELD(repeated_bytes)
476   TEST_MERGE_ONE_FIELD(repeated_nested_message)
477   TEST_MERGE_ONE_FIELD(repeated_foreign_message)
478   TEST_MERGE_ONE_FIELD(repeated_import_message)
479   TEST_MERGE_ONE_FIELD(repeated_nested_enum)
480   TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
481   TEST_MERGE_ONE_FIELD(repeated_import_enum)
482 #undef TEST_MERGE_ONE_FIELD
483 
484   // Test merge nested fields.
485   NestedTestAllTypes nested_src, nested_dst;
486   nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
487   nested_src.mutable_child()
488       ->mutable_child()
489       ->mutable_payload()
490       ->set_optional_int32(5678);
491   FieldMask mask;
492   FieldMaskUtil::FromString("child.payload", &mask);
493   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
494   EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
495   EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
496 
497   FieldMaskUtil::FromString("child.child.payload", &mask);
498   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
499   EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
500   EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
501 
502   nested_dst.Clear();
503   FieldMaskUtil::FromString("child.child.payload", &mask);
504   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
505   EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
506   EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
507 
508   nested_dst.Clear();
509   FieldMaskUtil::FromString("child", &mask);
510   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
511   EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
512   EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
513 
514   // Test MergeOptions.
515 
516   nested_dst.Clear();
517   nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
518   // Message fields will be merged by default.
519   FieldMaskUtil::FromString("child.payload", &mask);
520   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
521   EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
522   EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
523   // Change the behavior to replace message fields.
524   options.set_replace_message_fields(true);
525   FieldMaskUtil::FromString("child.payload", &mask);
526   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
527   EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
528   EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
529 
530   // By default, fields missing in source are not cleared in destination.
531   options.set_replace_message_fields(false);
532   nested_dst.mutable_payload();
533   EXPECT_TRUE(nested_dst.has_payload());
534   FieldMaskUtil::FromString("payload", &mask);
535   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
536   EXPECT_TRUE(nested_dst.has_payload());
537   // But they are cleared when replacing message fields.
538   options.set_replace_message_fields(true);
539   nested_dst.Clear();
540   nested_dst.mutable_payload();
541   FieldMaskUtil::FromString("payload", &mask);
542   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
543   EXPECT_FALSE(nested_dst.has_payload());
544 
545   nested_src.mutable_payload()->add_repeated_int32(1234);
546   nested_dst.mutable_payload()->add_repeated_int32(5678);
547   // Repeated fields will be appended by default.
548   FieldMaskUtil::FromString("payload.repeated_int32", &mask);
549   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
550   ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
551   EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
552   EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
553   // Change the behavior to replace repeated fields.
554   options.set_replace_repeated_fields(true);
555   FieldMaskUtil::FromString("payload.repeated_int32", &mask);
556   FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
557   ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
558   EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
559 }
560 
TEST(FieldMaskUtilTest,TrimMessage)561 TEST(FieldMaskUtilTest, TrimMessage) {
562 #define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name)    \
563   {                                                  \
564     TestAllTypes msg;                                \
565     TestUtil::SetAllFields(&msg);                    \
566     TestAllTypes tmp;                                \
567     tmp.set_##field_name(msg.field_name());          \
568     FieldMask mask;                                  \
569     mask.add_paths(#field_name);                     \
570     FieldMaskUtil::TrimMessage(mask, &msg);          \
571     EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
572   }
573   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int32)
574   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int64)
575   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint32)
576   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint64)
577   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint32)
578   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint64)
579   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed32)
580   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed64)
581   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed32)
582   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed64)
583   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_float)
584   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_double)
585   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bool)
586   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_string)
587   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bytes)
588   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_nested_enum)
589   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
590   TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_import_enum)
591 #undef TEST_TRIM_ONE_PRIMITIVE_FIELD
592 
593 #define TEST_TRIM_ONE_FIELD(field_name)              \
594   {                                                  \
595     TestAllTypes msg;                                \
596     TestUtil::SetAllFields(&msg);                    \
597     TestAllTypes tmp;                                \
598     *tmp.mutable_##field_name() = msg.field_name();  \
599     FieldMask mask;                                  \
600     mask.add_paths(#field_name);                     \
601     FieldMaskUtil::TrimMessage(mask, &msg);          \
602     EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
603   }
604   TEST_TRIM_ONE_FIELD(optional_nested_message)
605   TEST_TRIM_ONE_FIELD(optional_foreign_message)
606   TEST_TRIM_ONE_FIELD(optional_import_message)
607 
608   TEST_TRIM_ONE_FIELD(repeated_int32)
609   TEST_TRIM_ONE_FIELD(repeated_int64)
610   TEST_TRIM_ONE_FIELD(repeated_uint32)
611   TEST_TRIM_ONE_FIELD(repeated_uint64)
612   TEST_TRIM_ONE_FIELD(repeated_sint32)
613   TEST_TRIM_ONE_FIELD(repeated_sint64)
614   TEST_TRIM_ONE_FIELD(repeated_fixed32)
615   TEST_TRIM_ONE_FIELD(repeated_fixed64)
616   TEST_TRIM_ONE_FIELD(repeated_sfixed32)
617   TEST_TRIM_ONE_FIELD(repeated_sfixed64)
618   TEST_TRIM_ONE_FIELD(repeated_float)
619   TEST_TRIM_ONE_FIELD(repeated_double)
620   TEST_TRIM_ONE_FIELD(repeated_bool)
621   TEST_TRIM_ONE_FIELD(repeated_string)
622   TEST_TRIM_ONE_FIELD(repeated_bytes)
623   TEST_TRIM_ONE_FIELD(repeated_nested_message)
624   TEST_TRIM_ONE_FIELD(repeated_foreign_message)
625   TEST_TRIM_ONE_FIELD(repeated_import_message)
626   TEST_TRIM_ONE_FIELD(repeated_nested_enum)
627   TEST_TRIM_ONE_FIELD(repeated_foreign_enum)
628   TEST_TRIM_ONE_FIELD(repeated_import_enum)
629 #undef TEST_TRIM_ONE_FIELD
630 
631   // Test trim nested fields.
632   NestedTestAllTypes nested_msg;
633   nested_msg.mutable_child()->mutable_payload()->set_optional_int32(1234);
634   nested_msg.mutable_child()
635       ->mutable_child()
636       ->mutable_payload()
637       ->set_optional_int32(5678);
638   NestedTestAllTypes trimmed_msg(nested_msg);
639   FieldMask mask;
640   FieldMaskUtil::FromString("child.payload", &mask);
641   FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
642   EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
643   EXPECT_EQ(0, trimmed_msg.child().child().payload().optional_int32());
644 
645   trimmed_msg = nested_msg;
646   FieldMaskUtil::FromString("child.child.payload", &mask);
647   FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
648   EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
649   EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
650 
651   trimmed_msg = nested_msg;
652   FieldMaskUtil::FromString("child", &mask);
653   FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
654   EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
655   EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
656 
657   trimmed_msg = nested_msg;
658   FieldMaskUtil::FromString("child.child", &mask);
659   FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
660   EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
661   EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
662 
663   // Verify than an empty FieldMask trims nothing
664   TestAllTypes all_types_msg;
665   TestUtil::SetAllFields(&all_types_msg);
666   TestAllTypes trimmed_all_types(all_types_msg);
667   FieldMask empty_mask;
668   FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types);
669   EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString());
670 
671   // Test trim required fields with keep_required_fields is set true.
672   FieldMaskUtil::TrimOptions options;
673   TestRequired required_msg_1;
674   required_msg_1.set_a(1234);
675   required_msg_1.set_b(3456);
676   required_msg_1.set_c(5678);
677   TestRequired trimmed_required_msg_1(required_msg_1);
678   FieldMaskUtil::FromString("dummy2", &mask);
679   options.set_keep_required_fields(true);
680   FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
681   EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
682 
683   // Test trim required fields with keep_required_fields is set false.
684   required_msg_1.clear_a();
685   required_msg_1.clear_b();
686   required_msg_1.clear_c();
687   options.set_keep_required_fields(false);
688   FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
689   EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
690 
691   // Test trim required message with keep_required_fields is set true.
692   TestRequiredMessage required_msg_2;
693   required_msg_2.mutable_optional_message()->set_a(1234);
694   required_msg_2.mutable_optional_message()->set_b(3456);
695   required_msg_2.mutable_optional_message()->set_c(5678);
696   required_msg_2.mutable_required_message()->set_a(1234);
697   required_msg_2.mutable_required_message()->set_b(3456);
698   required_msg_2.mutable_required_message()->set_c(5678);
699   required_msg_2.mutable_required_message()->set_dummy2(7890);
700   TestRequired* repeated_msg = required_msg_2.add_repeated_message();
701   repeated_msg->set_a(1234);
702   repeated_msg->set_b(3456);
703   repeated_msg->set_c(5678);
704   TestRequiredMessage trimmed_required_msg_2(required_msg_2);
705   FieldMaskUtil::FromString("optional_message.dummy2", &mask);
706   options.set_keep_required_fields(true);
707   required_msg_2.clear_repeated_message();
708   required_msg_2.mutable_required_message()->clear_dummy2();
709   FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
710   EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
711 
712   FieldMaskUtil::FromString("required_message", &mask);
713   required_msg_2.mutable_required_message()->set_dummy2(7890);
714   trimmed_required_msg_2.mutable_required_message()->set_dummy2(7890);
715   required_msg_2.clear_optional_message();
716   FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
717   EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
718 
719   // Test trim required message with keep_required_fields is set false.
720   FieldMaskUtil::FromString("required_message.dummy2", &mask);
721   required_msg_2.mutable_required_message()->clear_a();
722   required_msg_2.mutable_required_message()->clear_b();
723   required_msg_2.mutable_required_message()->clear_c();
724   options.set_keep_required_fields(false);
725   FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
726   EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
727 
728   // Verify that trimming an empty message has no effect. In particular, fields
729   // mentioned in the field mask should not be created or changed.
730   TestAllTypes empty_msg;
731   FieldMaskUtil::FromString(
732       "optional_int32,optional_bytes,optional_nested_message.bb", &mask);
733   FieldMaskUtil::TrimMessage(mask, &empty_msg);
734   EXPECT_FALSE(empty_msg.has_optional_int32());
735   EXPECT_FALSE(empty_msg.has_optional_bytes());
736   EXPECT_FALSE(empty_msg.has_optional_nested_message());
737 
738   // Verify trimming of oneof fields. This should work as expected even if
739   // multiple elements of the same oneof are included in the FieldMask.
740   TestAllTypes oneof_msg;
741   oneof_msg.set_oneof_uint32(11);
742   FieldMaskUtil::FromString("oneof_uint32,oneof_nested_message.bb", &mask);
743   FieldMaskUtil::TrimMessage(mask, &oneof_msg);
744   EXPECT_EQ(11, oneof_msg.oneof_uint32());
745 }
746 
TEST(FieldMaskUtilTest,TrimMessageReturnValue)747 TEST(FieldMaskUtilTest, TrimMessageReturnValue) {
748   FieldMask mask;
749   TestAllTypes trimed_msg;
750   TestAllTypes default_msg;
751 
752   // Field mask on optional field.
753   FieldMaskUtil::FromString("optional_int32", &mask);
754 
755   // Verify that if a message is updted by FieldMaskUtil::TrimMessage(), the
756   // function returns true.
757   // Test on primary field.
758   trimed_msg.set_optional_string("abc");
759   EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
760   EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
761   trimed_msg.Clear();
762 
763   // Test on repeated primary field.
764   trimed_msg.add_repeated_string("abc");
765   trimed_msg.add_repeated_string("def");
766   EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
767   EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
768   trimed_msg.Clear();
769 
770   // Test on nested message.
771   trimed_msg.mutable_optional_nested_message()->set_bb(123);
772   EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
773   EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
774   trimed_msg.Clear();
775 
776   // Test on repeated nested message.
777   trimed_msg.add_repeated_nested_message()->set_bb(123);
778   trimed_msg.add_repeated_nested_message()->set_bb(456);
779   EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
780   EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
781   trimed_msg.Clear();
782 
783   // Test on oneof field.
784   trimed_msg.set_oneof_uint32(123);
785   EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
786   EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
787   trimed_msg.Clear();
788 
789   // If there is no field set other then those whitelisted,
790   // FieldMaskUtil::TrimMessage() should return false.
791   trimed_msg.set_optional_int32(123);
792   EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
793   EXPECT_EQ(trimed_msg.optional_int32(), 123);
794   trimed_msg.Clear();
795 
796   // Field mask on repated field.
797   FieldMaskUtil::FromString("repeated_string", &mask);
798   trimed_msg.add_repeated_string("abc");
799   trimed_msg.add_repeated_string("def");
800   EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
801   EXPECT_EQ(trimed_msg.repeated_string(0), "abc");
802   EXPECT_EQ(trimed_msg.repeated_string(1), "def");
803   trimed_msg.Clear();
804 
805   // Field mask on nested message.
806   FieldMaskUtil::FromString("optional_nested_message.bb", &mask);
807   trimed_msg.mutable_optional_nested_message()->set_bb(123);
808   EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
809   EXPECT_EQ(trimed_msg.optional_nested_message().bb(), 123);
810   trimed_msg.Clear();
811 
812   // TODO(b/32443320): field mask on repeated nested message is not yet
813   // supported.
814 }
815 
816 
817 }  // namespace
818 }  // namespace util
819 }  // namespace protobuf
820 }  // namespace google
821