xref: /aosp_15_r20/external/libprotobuf-mutator/src/mutator.cc (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2016 Google Inc. All rights reserved.
2*fd525a9cSAndroid Build Coastguard Worker //
3*fd525a9cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*fd525a9cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*fd525a9cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*fd525a9cSAndroid Build Coastguard Worker //
7*fd525a9cSAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*fd525a9cSAndroid Build Coastguard Worker //
9*fd525a9cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*fd525a9cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*fd525a9cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*fd525a9cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*fd525a9cSAndroid Build Coastguard Worker // limitations under the License.
14*fd525a9cSAndroid Build Coastguard Worker 
15*fd525a9cSAndroid Build Coastguard Worker #include "src/mutator.h"
16*fd525a9cSAndroid Build Coastguard Worker 
17*fd525a9cSAndroid Build Coastguard Worker #include <algorithm>
18*fd525a9cSAndroid Build Coastguard Worker #include <bitset>
19*fd525a9cSAndroid Build Coastguard Worker #include <iostream>
20*fd525a9cSAndroid Build Coastguard Worker #include <map>
21*fd525a9cSAndroid Build Coastguard Worker #include <memory>
22*fd525a9cSAndroid Build Coastguard Worker #include <random>
23*fd525a9cSAndroid Build Coastguard Worker #include <string>
24*fd525a9cSAndroid Build Coastguard Worker #include <utility>
25*fd525a9cSAndroid Build Coastguard Worker #include <vector>
26*fd525a9cSAndroid Build Coastguard Worker 
27*fd525a9cSAndroid Build Coastguard Worker #include "src/field_instance.h"
28*fd525a9cSAndroid Build Coastguard Worker #include "src/utf8_fix.h"
29*fd525a9cSAndroid Build Coastguard Worker #include "src/weighted_reservoir_sampler.h"
30*fd525a9cSAndroid Build Coastguard Worker 
31*fd525a9cSAndroid Build Coastguard Worker namespace protobuf_mutator {
32*fd525a9cSAndroid Build Coastguard Worker 
33*fd525a9cSAndroid Build Coastguard Worker using google::protobuf::Any;
34*fd525a9cSAndroid Build Coastguard Worker using protobuf::Descriptor;
35*fd525a9cSAndroid Build Coastguard Worker using protobuf::FieldDescriptor;
36*fd525a9cSAndroid Build Coastguard Worker using protobuf::FileDescriptor;
37*fd525a9cSAndroid Build Coastguard Worker using protobuf::Message;
38*fd525a9cSAndroid Build Coastguard Worker using protobuf::OneofDescriptor;
39*fd525a9cSAndroid Build Coastguard Worker using protobuf::Reflection;
40*fd525a9cSAndroid Build Coastguard Worker using protobuf::util::MessageDifferencer;
41*fd525a9cSAndroid Build Coastguard Worker using std::placeholders::_1;
42*fd525a9cSAndroid Build Coastguard Worker 
43*fd525a9cSAndroid Build Coastguard Worker namespace {
44*fd525a9cSAndroid Build Coastguard Worker 
45*fd525a9cSAndroid Build Coastguard Worker const int kMaxInitializeDepth = 200;
46*fd525a9cSAndroid Build Coastguard Worker const uint64_t kDefaultMutateWeight = 1000000;
47*fd525a9cSAndroid Build Coastguard Worker 
48*fd525a9cSAndroid Build Coastguard Worker enum class Mutation : uint8_t {
49*fd525a9cSAndroid Build Coastguard Worker   None,
50*fd525a9cSAndroid Build Coastguard Worker   Add,     // Adds new field with default value.
51*fd525a9cSAndroid Build Coastguard Worker   Mutate,  // Mutates field contents.
52*fd525a9cSAndroid Build Coastguard Worker   Delete,  // Deletes field.
53*fd525a9cSAndroid Build Coastguard Worker   Copy,    // Copy values copied from another field.
54*fd525a9cSAndroid Build Coastguard Worker   Clone,   // Create new field with value copied from another.
55*fd525a9cSAndroid Build Coastguard Worker 
56*fd525a9cSAndroid Build Coastguard Worker   Last = Clone,
57*fd525a9cSAndroid Build Coastguard Worker };
58*fd525a9cSAndroid Build Coastguard Worker 
59*fd525a9cSAndroid Build Coastguard Worker using MutationBitset = std::bitset<static_cast<size_t>(Mutation::Last) + 1>;
60*fd525a9cSAndroid Build Coastguard Worker 
61*fd525a9cSAndroid Build Coastguard Worker using Messages = std::vector<Message*>;
62*fd525a9cSAndroid Build Coastguard Worker using ConstMessages = std::vector<const Message*>;
63*fd525a9cSAndroid Build Coastguard Worker 
64*fd525a9cSAndroid Build Coastguard Worker // Return random integer from [0, count)
GetRandomIndex(RandomEngine * random,size_t count)65*fd525a9cSAndroid Build Coastguard Worker size_t GetRandomIndex(RandomEngine* random, size_t count) {
66*fd525a9cSAndroid Build Coastguard Worker   assert(count > 0);
67*fd525a9cSAndroid Build Coastguard Worker   if (count == 1) return 0;
68*fd525a9cSAndroid Build Coastguard Worker   return std::uniform_int_distribution<size_t>(0, count - 1)(*random);
69*fd525a9cSAndroid Build Coastguard Worker }
70*fd525a9cSAndroid Build Coastguard Worker 
71*fd525a9cSAndroid Build Coastguard Worker // Flips random bit in the buffer.
FlipBit(size_t size,uint8_t * bytes,RandomEngine * random)72*fd525a9cSAndroid Build Coastguard Worker void FlipBit(size_t size, uint8_t* bytes, RandomEngine* random) {
73*fd525a9cSAndroid Build Coastguard Worker   size_t bit = GetRandomIndex(random, size * 8);
74*fd525a9cSAndroid Build Coastguard Worker   bytes[bit / 8] ^= (1u << (bit % 8));
75*fd525a9cSAndroid Build Coastguard Worker }
76*fd525a9cSAndroid Build Coastguard Worker 
77*fd525a9cSAndroid Build Coastguard Worker // Flips random bit in the value.
78*fd525a9cSAndroid Build Coastguard Worker template <class T>
FlipBit(T value,RandomEngine * random)79*fd525a9cSAndroid Build Coastguard Worker T FlipBit(T value, RandomEngine* random) {
80*fd525a9cSAndroid Build Coastguard Worker   FlipBit(sizeof(value), reinterpret_cast<uint8_t*>(&value), random);
81*fd525a9cSAndroid Build Coastguard Worker   return value;
82*fd525a9cSAndroid Build Coastguard Worker }
83*fd525a9cSAndroid Build Coastguard Worker 
84*fd525a9cSAndroid Build Coastguard Worker // Return true with probability about 1-of-n.
GetRandomBool(RandomEngine * random,size_t n=2)85*fd525a9cSAndroid Build Coastguard Worker bool GetRandomBool(RandomEngine* random, size_t n = 2) {
86*fd525a9cSAndroid Build Coastguard Worker   return GetRandomIndex(random, n) == 0;
87*fd525a9cSAndroid Build Coastguard Worker }
88*fd525a9cSAndroid Build Coastguard Worker 
IsProto3SimpleField(const FieldDescriptor & field)89*fd525a9cSAndroid Build Coastguard Worker bool IsProto3SimpleField(const FieldDescriptor& field) {
90*fd525a9cSAndroid Build Coastguard Worker   assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
91*fd525a9cSAndroid Build Coastguard Worker          field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2);
92*fd525a9cSAndroid Build Coastguard Worker   return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
93*fd525a9cSAndroid Build Coastguard Worker          field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
94*fd525a9cSAndroid Build Coastguard Worker          !field.containing_oneof() && !field.is_repeated();
95*fd525a9cSAndroid Build Coastguard Worker }
96*fd525a9cSAndroid Build Coastguard Worker 
97*fd525a9cSAndroid Build Coastguard Worker struct CreateDefaultField : public FieldFunction<CreateDefaultField> {
98*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0111::CreateDefaultField99*fd525a9cSAndroid Build Coastguard Worker   void ForType(const FieldInstance& field) const {
100*fd525a9cSAndroid Build Coastguard Worker     T value;
101*fd525a9cSAndroid Build Coastguard Worker     field.GetDefault(&value);
102*fd525a9cSAndroid Build Coastguard Worker     field.Create(value);
103*fd525a9cSAndroid Build Coastguard Worker   }
104*fd525a9cSAndroid Build Coastguard Worker };
105*fd525a9cSAndroid Build Coastguard Worker 
106*fd525a9cSAndroid Build Coastguard Worker struct DeleteField : public FieldFunction<DeleteField> {
107*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0111::DeleteField108*fd525a9cSAndroid Build Coastguard Worker   void ForType(const FieldInstance& field) const {
109*fd525a9cSAndroid Build Coastguard Worker     field.Delete();
110*fd525a9cSAndroid Build Coastguard Worker   }
111*fd525a9cSAndroid Build Coastguard Worker };
112*fd525a9cSAndroid Build Coastguard Worker 
113*fd525a9cSAndroid Build Coastguard Worker struct CopyField : public FieldFunction<CopyField> {
114*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0111::CopyField115*fd525a9cSAndroid Build Coastguard Worker   void ForType(const ConstFieldInstance& source,
116*fd525a9cSAndroid Build Coastguard Worker                const FieldInstance& field) const {
117*fd525a9cSAndroid Build Coastguard Worker     T value;
118*fd525a9cSAndroid Build Coastguard Worker     source.Load(&value);
119*fd525a9cSAndroid Build Coastguard Worker     field.Store(value);
120*fd525a9cSAndroid Build Coastguard Worker   }
121*fd525a9cSAndroid Build Coastguard Worker };
122*fd525a9cSAndroid Build Coastguard Worker 
123*fd525a9cSAndroid Build Coastguard Worker struct AppendField : public FieldFunction<AppendField> {
124*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0111::AppendField125*fd525a9cSAndroid Build Coastguard Worker   void ForType(const ConstFieldInstance& source,
126*fd525a9cSAndroid Build Coastguard Worker                const FieldInstance& field) const {
127*fd525a9cSAndroid Build Coastguard Worker     T value;
128*fd525a9cSAndroid Build Coastguard Worker     source.Load(&value);
129*fd525a9cSAndroid Build Coastguard Worker     field.Create(value);
130*fd525a9cSAndroid Build Coastguard Worker   }
131*fd525a9cSAndroid Build Coastguard Worker };
132*fd525a9cSAndroid Build Coastguard Worker 
133*fd525a9cSAndroid Build Coastguard Worker class CanCopyAndDifferentField
134*fd525a9cSAndroid Build Coastguard Worker     : public FieldFunction<CanCopyAndDifferentField, bool> {
135*fd525a9cSAndroid Build Coastguard Worker  public:
136*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForType(const ConstFieldInstance & src,const ConstFieldInstance & dst,int size_increase_hint) const137*fd525a9cSAndroid Build Coastguard Worker   bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst,
138*fd525a9cSAndroid Build Coastguard Worker                int size_increase_hint) const {
139*fd525a9cSAndroid Build Coastguard Worker     T s;
140*fd525a9cSAndroid Build Coastguard Worker     src.Load(&s);
141*fd525a9cSAndroid Build Coastguard Worker     if (!dst.CanStore(s)) return false;
142*fd525a9cSAndroid Build Coastguard Worker     T d;
143*fd525a9cSAndroid Build Coastguard Worker     dst.Load(&d);
144*fd525a9cSAndroid Build Coastguard Worker     return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d);
145*fd525a9cSAndroid Build Coastguard Worker   }
146*fd525a9cSAndroid Build Coastguard Worker 
147*fd525a9cSAndroid Build Coastguard Worker  private:
IsEqual(const ConstFieldInstance::Enum & a,const ConstFieldInstance::Enum & b) const148*fd525a9cSAndroid Build Coastguard Worker   bool IsEqual(const ConstFieldInstance::Enum& a,
149*fd525a9cSAndroid Build Coastguard Worker                const ConstFieldInstance::Enum& b) const {
150*fd525a9cSAndroid Build Coastguard Worker     assert(a.count == b.count);
151*fd525a9cSAndroid Build Coastguard Worker     return a.index == b.index;
152*fd525a9cSAndroid Build Coastguard Worker   }
153*fd525a9cSAndroid Build Coastguard Worker 
IsEqual(const std::unique_ptr<Message> & a,const std::unique_ptr<Message> & b) const154*fd525a9cSAndroid Build Coastguard Worker   bool IsEqual(const std::unique_ptr<Message>& a,
155*fd525a9cSAndroid Build Coastguard Worker                const std::unique_ptr<Message>& b) const {
156*fd525a9cSAndroid Build Coastguard Worker     return MessageDifferencer::Equals(*a, *b);
157*fd525a9cSAndroid Build Coastguard Worker   }
158*fd525a9cSAndroid Build Coastguard Worker 
159*fd525a9cSAndroid Build Coastguard Worker   template <class T>
IsEqual(const T & a,const T & b) const160*fd525a9cSAndroid Build Coastguard Worker   bool IsEqual(const T& a, const T& b) const {
161*fd525a9cSAndroid Build Coastguard Worker     return a == b;
162*fd525a9cSAndroid Build Coastguard Worker   }
163*fd525a9cSAndroid Build Coastguard Worker 
SizeDiff(const std::unique_ptr<Message> & src,const std::unique_ptr<Message> & dst) const164*fd525a9cSAndroid Build Coastguard Worker   int64_t SizeDiff(const std::unique_ptr<Message>& src,
165*fd525a9cSAndroid Build Coastguard Worker                    const std::unique_ptr<Message>& dst) const {
166*fd525a9cSAndroid Build Coastguard Worker     return src->ByteSizeLong() - dst->ByteSizeLong();
167*fd525a9cSAndroid Build Coastguard Worker   }
168*fd525a9cSAndroid Build Coastguard Worker 
SizeDiff(const std::string & src,const std::string & dst) const169*fd525a9cSAndroid Build Coastguard Worker   int64_t SizeDiff(const std::string& src, const std::string& dst) const {
170*fd525a9cSAndroid Build Coastguard Worker     return src.size() - dst.size();
171*fd525a9cSAndroid Build Coastguard Worker   }
172*fd525a9cSAndroid Build Coastguard Worker 
173*fd525a9cSAndroid Build Coastguard Worker   template <class T>
SizeDiff(const T &,const T &) const174*fd525a9cSAndroid Build Coastguard Worker   int64_t SizeDiff(const T&, const T&) const {
175*fd525a9cSAndroid Build Coastguard Worker     return 0;
176*fd525a9cSAndroid Build Coastguard Worker   }
177*fd525a9cSAndroid Build Coastguard Worker };
178*fd525a9cSAndroid Build Coastguard Worker 
179*fd525a9cSAndroid Build Coastguard Worker // Selects random field and mutation from the given proto message.
180*fd525a9cSAndroid Build Coastguard Worker class MutationSampler {
181*fd525a9cSAndroid Build Coastguard Worker  public:
MutationSampler(bool keep_initialized,MutationBitset allowed_mutations,RandomEngine * random)182*fd525a9cSAndroid Build Coastguard Worker   MutationSampler(bool keep_initialized, MutationBitset allowed_mutations,
183*fd525a9cSAndroid Build Coastguard Worker                   RandomEngine* random)
184*fd525a9cSAndroid Build Coastguard Worker       : keep_initialized_(keep_initialized),
185*fd525a9cSAndroid Build Coastguard Worker         allowed_mutations_(allowed_mutations),
186*fd525a9cSAndroid Build Coastguard Worker         random_(random),
187*fd525a9cSAndroid Build Coastguard Worker         sampler_(random) {}
188*fd525a9cSAndroid Build Coastguard Worker 
189*fd525a9cSAndroid Build Coastguard Worker   // Returns selected field.
field() const190*fd525a9cSAndroid Build Coastguard Worker   const FieldInstance& field() const { return sampler_.selected().field; }
191*fd525a9cSAndroid Build Coastguard Worker 
192*fd525a9cSAndroid Build Coastguard Worker   // Returns selected mutation.
mutation() const193*fd525a9cSAndroid Build Coastguard Worker   Mutation mutation() const { return sampler_.selected().mutation; }
194*fd525a9cSAndroid Build Coastguard Worker 
Sample(Message * message)195*fd525a9cSAndroid Build Coastguard Worker   void Sample(Message* message) {
196*fd525a9cSAndroid Build Coastguard Worker     SampleImpl(message);
197*fd525a9cSAndroid Build Coastguard Worker     assert(mutation() != Mutation::None ||
198*fd525a9cSAndroid Build Coastguard Worker            !allowed_mutations_[static_cast<size_t>(Mutation::Mutate)] ||
199*fd525a9cSAndroid Build Coastguard Worker            message->GetDescriptor()->field_count() == 0);
200*fd525a9cSAndroid Build Coastguard Worker   }
201*fd525a9cSAndroid Build Coastguard Worker 
202*fd525a9cSAndroid Build Coastguard Worker  private:
SampleImpl(Message * message)203*fd525a9cSAndroid Build Coastguard Worker   void SampleImpl(Message* message) {
204*fd525a9cSAndroid Build Coastguard Worker     const Descriptor* descriptor = message->GetDescriptor();
205*fd525a9cSAndroid Build Coastguard Worker     const Reflection* reflection = message->GetReflection();
206*fd525a9cSAndroid Build Coastguard Worker 
207*fd525a9cSAndroid Build Coastguard Worker     int field_count = descriptor->field_count();
208*fd525a9cSAndroid Build Coastguard Worker     for (int i = 0; i < field_count; ++i) {
209*fd525a9cSAndroid Build Coastguard Worker       const FieldDescriptor* field = descriptor->field(i);
210*fd525a9cSAndroid Build Coastguard Worker       if (const OneofDescriptor* oneof = field->containing_oneof()) {
211*fd525a9cSAndroid Build Coastguard Worker         // Handle entire oneof group on the first field.
212*fd525a9cSAndroid Build Coastguard Worker         if (field->index_in_oneof() == 0) {
213*fd525a9cSAndroid Build Coastguard Worker           assert(oneof->field_count());
214*fd525a9cSAndroid Build Coastguard Worker           const FieldDescriptor* current_field =
215*fd525a9cSAndroid Build Coastguard Worker               reflection->GetOneofFieldDescriptor(*message, oneof);
216*fd525a9cSAndroid Build Coastguard Worker           for (;;) {
217*fd525a9cSAndroid Build Coastguard Worker             const FieldDescriptor* add_field =
218*fd525a9cSAndroid Build Coastguard Worker                 oneof->field(GetRandomIndex(random_, oneof->field_count()));
219*fd525a9cSAndroid Build Coastguard Worker             if (add_field != current_field) {
220*fd525a9cSAndroid Build Coastguard Worker               Try({message, add_field}, Mutation::Add);
221*fd525a9cSAndroid Build Coastguard Worker               Try({message, add_field}, Mutation::Clone);
222*fd525a9cSAndroid Build Coastguard Worker               break;
223*fd525a9cSAndroid Build Coastguard Worker             }
224*fd525a9cSAndroid Build Coastguard Worker             if (oneof->field_count() < 2) break;
225*fd525a9cSAndroid Build Coastguard Worker           }
226*fd525a9cSAndroid Build Coastguard Worker           if (current_field) {
227*fd525a9cSAndroid Build Coastguard Worker             if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
228*fd525a9cSAndroid Build Coastguard Worker               Try({message, current_field}, Mutation::Mutate);
229*fd525a9cSAndroid Build Coastguard Worker             Try({message, current_field}, Mutation::Delete);
230*fd525a9cSAndroid Build Coastguard Worker             Try({message, current_field}, Mutation::Copy);
231*fd525a9cSAndroid Build Coastguard Worker           }
232*fd525a9cSAndroid Build Coastguard Worker         }
233*fd525a9cSAndroid Build Coastguard Worker       } else {
234*fd525a9cSAndroid Build Coastguard Worker         if (field->is_repeated()) {
235*fd525a9cSAndroid Build Coastguard Worker           int field_size = reflection->FieldSize(*message, field);
236*fd525a9cSAndroid Build Coastguard Worker           size_t random_index = GetRandomIndex(random_, field_size + 1);
237*fd525a9cSAndroid Build Coastguard Worker           Try({message, field, random_index}, Mutation::Add);
238*fd525a9cSAndroid Build Coastguard Worker           Try({message, field, random_index}, Mutation::Clone);
239*fd525a9cSAndroid Build Coastguard Worker 
240*fd525a9cSAndroid Build Coastguard Worker           if (field_size) {
241*fd525a9cSAndroid Build Coastguard Worker             size_t random_index = GetRandomIndex(random_, field_size);
242*fd525a9cSAndroid Build Coastguard Worker             if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
243*fd525a9cSAndroid Build Coastguard Worker               Try({message, field, random_index}, Mutation::Mutate);
244*fd525a9cSAndroid Build Coastguard Worker             Try({message, field, random_index}, Mutation::Delete);
245*fd525a9cSAndroid Build Coastguard Worker             Try({message, field, random_index}, Mutation::Copy);
246*fd525a9cSAndroid Build Coastguard Worker           }
247*fd525a9cSAndroid Build Coastguard Worker         } else {
248*fd525a9cSAndroid Build Coastguard Worker           if (reflection->HasField(*message, field) ||
249*fd525a9cSAndroid Build Coastguard Worker               IsProto3SimpleField(*field)) {
250*fd525a9cSAndroid Build Coastguard Worker             if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
251*fd525a9cSAndroid Build Coastguard Worker               Try({message, field}, Mutation::Mutate);
252*fd525a9cSAndroid Build Coastguard Worker             if (!IsProto3SimpleField(*field) &&
253*fd525a9cSAndroid Build Coastguard Worker                 (!field->is_required() || !keep_initialized_)) {
254*fd525a9cSAndroid Build Coastguard Worker               Try({message, field}, Mutation::Delete);
255*fd525a9cSAndroid Build Coastguard Worker             }
256*fd525a9cSAndroid Build Coastguard Worker             Try({message, field}, Mutation::Copy);
257*fd525a9cSAndroid Build Coastguard Worker           } else {
258*fd525a9cSAndroid Build Coastguard Worker             Try({message, field}, Mutation::Add);
259*fd525a9cSAndroid Build Coastguard Worker             Try({message, field}, Mutation::Clone);
260*fd525a9cSAndroid Build Coastguard Worker           }
261*fd525a9cSAndroid Build Coastguard Worker         }
262*fd525a9cSAndroid Build Coastguard Worker       }
263*fd525a9cSAndroid Build Coastguard Worker 
264*fd525a9cSAndroid Build Coastguard Worker       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
265*fd525a9cSAndroid Build Coastguard Worker         if (field->is_repeated()) {
266*fd525a9cSAndroid Build Coastguard Worker           const int field_size = reflection->FieldSize(*message, field);
267*fd525a9cSAndroid Build Coastguard Worker           for (int j = 0; j < field_size; ++j)
268*fd525a9cSAndroid Build Coastguard Worker             SampleImpl(reflection->MutableRepeatedMessage(message, field, j));
269*fd525a9cSAndroid Build Coastguard Worker         } else if (reflection->HasField(*message, field)) {
270*fd525a9cSAndroid Build Coastguard Worker           SampleImpl(reflection->MutableMessage(message, field));
271*fd525a9cSAndroid Build Coastguard Worker         }
272*fd525a9cSAndroid Build Coastguard Worker       }
273*fd525a9cSAndroid Build Coastguard Worker     }
274*fd525a9cSAndroid Build Coastguard Worker   }
275*fd525a9cSAndroid Build Coastguard Worker 
Try(const FieldInstance & field,Mutation mutation)276*fd525a9cSAndroid Build Coastguard Worker   void Try(const FieldInstance& field, Mutation mutation) {
277*fd525a9cSAndroid Build Coastguard Worker     assert(mutation != Mutation::None);
278*fd525a9cSAndroid Build Coastguard Worker     if (!allowed_mutations_[static_cast<size_t>(mutation)]) return;
279*fd525a9cSAndroid Build Coastguard Worker     sampler_.Try(kDefaultMutateWeight, {field, mutation});
280*fd525a9cSAndroid Build Coastguard Worker   }
281*fd525a9cSAndroid Build Coastguard Worker 
282*fd525a9cSAndroid Build Coastguard Worker   bool keep_initialized_ = false;
283*fd525a9cSAndroid Build Coastguard Worker   MutationBitset allowed_mutations_;
284*fd525a9cSAndroid Build Coastguard Worker 
285*fd525a9cSAndroid Build Coastguard Worker   RandomEngine* random_;
286*fd525a9cSAndroid Build Coastguard Worker 
287*fd525a9cSAndroid Build Coastguard Worker   struct Result {
288*fd525a9cSAndroid Build Coastguard Worker     Result() = default;
Resultprotobuf_mutator::__anonab369fae0111::MutationSampler::Result289*fd525a9cSAndroid Build Coastguard Worker     Result(const FieldInstance& f, Mutation m) : field(f), mutation(m) {}
290*fd525a9cSAndroid Build Coastguard Worker 
291*fd525a9cSAndroid Build Coastguard Worker     FieldInstance field;
292*fd525a9cSAndroid Build Coastguard Worker     Mutation mutation = Mutation::None;
293*fd525a9cSAndroid Build Coastguard Worker   };
294*fd525a9cSAndroid Build Coastguard Worker   WeightedReservoirSampler<Result, RandomEngine> sampler_;
295*fd525a9cSAndroid Build Coastguard Worker };
296*fd525a9cSAndroid Build Coastguard Worker 
297*fd525a9cSAndroid Build Coastguard Worker // Selects random field of compatible type to use for clone mutations.
298*fd525a9cSAndroid Build Coastguard Worker class DataSourceSampler {
299*fd525a9cSAndroid Build Coastguard Worker  public:
DataSourceSampler(const ConstFieldInstance & match,RandomEngine * random,int size_increase_hint)300*fd525a9cSAndroid Build Coastguard Worker   DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
301*fd525a9cSAndroid Build Coastguard Worker                     int size_increase_hint)
302*fd525a9cSAndroid Build Coastguard Worker       : match_(match),
303*fd525a9cSAndroid Build Coastguard Worker         random_(random),
304*fd525a9cSAndroid Build Coastguard Worker         size_increase_hint_(size_increase_hint),
305*fd525a9cSAndroid Build Coastguard Worker         sampler_(random) {}
306*fd525a9cSAndroid Build Coastguard Worker 
Sample(const Message & message)307*fd525a9cSAndroid Build Coastguard Worker   void Sample(const Message& message) { SampleImpl(message); }
308*fd525a9cSAndroid Build Coastguard Worker 
309*fd525a9cSAndroid Build Coastguard Worker   // Returns selected field.
field() const310*fd525a9cSAndroid Build Coastguard Worker   const ConstFieldInstance& field() const {
311*fd525a9cSAndroid Build Coastguard Worker     assert(!IsEmpty());
312*fd525a9cSAndroid Build Coastguard Worker     return sampler_.selected();
313*fd525a9cSAndroid Build Coastguard Worker   }
314*fd525a9cSAndroid Build Coastguard Worker 
IsEmpty() const315*fd525a9cSAndroid Build Coastguard Worker   bool IsEmpty() const { return sampler_.IsEmpty(); }
316*fd525a9cSAndroid Build Coastguard Worker 
317*fd525a9cSAndroid Build Coastguard Worker  private:
SampleImpl(const Message & message)318*fd525a9cSAndroid Build Coastguard Worker   void SampleImpl(const Message& message) {
319*fd525a9cSAndroid Build Coastguard Worker     const Descriptor* descriptor = message.GetDescriptor();
320*fd525a9cSAndroid Build Coastguard Worker     const Reflection* reflection = message.GetReflection();
321*fd525a9cSAndroid Build Coastguard Worker 
322*fd525a9cSAndroid Build Coastguard Worker     int field_count = descriptor->field_count();
323*fd525a9cSAndroid Build Coastguard Worker     for (int i = 0; i < field_count; ++i) {
324*fd525a9cSAndroid Build Coastguard Worker       const FieldDescriptor* field = descriptor->field(i);
325*fd525a9cSAndroid Build Coastguard Worker       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
326*fd525a9cSAndroid Build Coastguard Worker         if (field->is_repeated()) {
327*fd525a9cSAndroid Build Coastguard Worker           const int field_size = reflection->FieldSize(message, field);
328*fd525a9cSAndroid Build Coastguard Worker           for (int j = 0; j < field_size; ++j) {
329*fd525a9cSAndroid Build Coastguard Worker             SampleImpl(reflection->GetRepeatedMessage(message, field, j));
330*fd525a9cSAndroid Build Coastguard Worker           }
331*fd525a9cSAndroid Build Coastguard Worker         } else if (reflection->HasField(message, field)) {
332*fd525a9cSAndroid Build Coastguard Worker           SampleImpl(reflection->GetMessage(message, field));
333*fd525a9cSAndroid Build Coastguard Worker         }
334*fd525a9cSAndroid Build Coastguard Worker       }
335*fd525a9cSAndroid Build Coastguard Worker 
336*fd525a9cSAndroid Build Coastguard Worker       if (field->cpp_type() != match_.cpp_type()) continue;
337*fd525a9cSAndroid Build Coastguard Worker       if (match_.cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
338*fd525a9cSAndroid Build Coastguard Worker         if (field->enum_type() != match_.enum_type()) continue;
339*fd525a9cSAndroid Build Coastguard Worker       } else if (match_.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
340*fd525a9cSAndroid Build Coastguard Worker         if (field->message_type() != match_.message_type()) continue;
341*fd525a9cSAndroid Build Coastguard Worker       }
342*fd525a9cSAndroid Build Coastguard Worker 
343*fd525a9cSAndroid Build Coastguard Worker       if (field->is_repeated()) {
344*fd525a9cSAndroid Build Coastguard Worker         if (int field_size = reflection->FieldSize(message, field)) {
345*fd525a9cSAndroid Build Coastguard Worker           ConstFieldInstance source(&message, field,
346*fd525a9cSAndroid Build Coastguard Worker                                     GetRandomIndex(random_, field_size));
347*fd525a9cSAndroid Build Coastguard Worker           if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
348*fd525a9cSAndroid Build Coastguard Worker             sampler_.Try(field_size, source);
349*fd525a9cSAndroid Build Coastguard Worker         }
350*fd525a9cSAndroid Build Coastguard Worker       } else {
351*fd525a9cSAndroid Build Coastguard Worker         if (reflection->HasField(message, field)) {
352*fd525a9cSAndroid Build Coastguard Worker           ConstFieldInstance source(&message, field);
353*fd525a9cSAndroid Build Coastguard Worker           if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
354*fd525a9cSAndroid Build Coastguard Worker             sampler_.Try(1, source);
355*fd525a9cSAndroid Build Coastguard Worker         }
356*fd525a9cSAndroid Build Coastguard Worker       }
357*fd525a9cSAndroid Build Coastguard Worker     }
358*fd525a9cSAndroid Build Coastguard Worker   }
359*fd525a9cSAndroid Build Coastguard Worker 
360*fd525a9cSAndroid Build Coastguard Worker   ConstFieldInstance match_;
361*fd525a9cSAndroid Build Coastguard Worker   RandomEngine* random_;
362*fd525a9cSAndroid Build Coastguard Worker   int size_increase_hint_;
363*fd525a9cSAndroid Build Coastguard Worker 
364*fd525a9cSAndroid Build Coastguard Worker   WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
365*fd525a9cSAndroid Build Coastguard Worker };
366*fd525a9cSAndroid Build Coastguard Worker 
367*fd525a9cSAndroid Build Coastguard Worker using UnpackedAny =
368*fd525a9cSAndroid Build Coastguard Worker     std::unordered_map<const Message*, std::unique_ptr<Message>>;
369*fd525a9cSAndroid Build Coastguard Worker 
GetAnyTypeDescriptor(const Any & any)370*fd525a9cSAndroid Build Coastguard Worker const Descriptor* GetAnyTypeDescriptor(const Any& any) {
371*fd525a9cSAndroid Build Coastguard Worker   std::string type_name;
372*fd525a9cSAndroid Build Coastguard Worker   if (!Any::ParseAnyTypeUrl(std::string(any.type_url()), &type_name))
373*fd525a9cSAndroid Build Coastguard Worker     return nullptr;
374*fd525a9cSAndroid Build Coastguard Worker   return any.descriptor()->file()->pool()->FindMessageTypeByName(type_name);
375*fd525a9cSAndroid Build Coastguard Worker }
376*fd525a9cSAndroid Build Coastguard Worker 
UnpackAny(const Any & any)377*fd525a9cSAndroid Build Coastguard Worker std::unique_ptr<Message> UnpackAny(const Any& any) {
378*fd525a9cSAndroid Build Coastguard Worker   const Descriptor* desc = GetAnyTypeDescriptor(any);
379*fd525a9cSAndroid Build Coastguard Worker   if (!desc) return {};
380*fd525a9cSAndroid Build Coastguard Worker   std::unique_ptr<Message> message(
381*fd525a9cSAndroid Build Coastguard Worker       any.GetReflection()->GetMessageFactory()->GetPrototype(desc)->New());
382*fd525a9cSAndroid Build Coastguard Worker   message->ParsePartialFromString(std::string(any.value()));
383*fd525a9cSAndroid Build Coastguard Worker   return message;
384*fd525a9cSAndroid Build Coastguard Worker }
385*fd525a9cSAndroid Build Coastguard Worker 
CastToAny(const Message * message)386*fd525a9cSAndroid Build Coastguard Worker const Any* CastToAny(const Message* message) {
387*fd525a9cSAndroid Build Coastguard Worker   return Any::GetDescriptor() == message->GetDescriptor()
388*fd525a9cSAndroid Build Coastguard Worker              ? static_cast<const Any*>(message)
389*fd525a9cSAndroid Build Coastguard Worker              : nullptr;
390*fd525a9cSAndroid Build Coastguard Worker }
391*fd525a9cSAndroid Build Coastguard Worker 
CastToAny(Message * message)392*fd525a9cSAndroid Build Coastguard Worker Any* CastToAny(Message* message) {
393*fd525a9cSAndroid Build Coastguard Worker   return Any::GetDescriptor() == message->GetDescriptor()
394*fd525a9cSAndroid Build Coastguard Worker              ? static_cast<Any*>(message)
395*fd525a9cSAndroid Build Coastguard Worker              : nullptr;
396*fd525a9cSAndroid Build Coastguard Worker }
397*fd525a9cSAndroid Build Coastguard Worker 
UnpackIfAny(const Message & message)398*fd525a9cSAndroid Build Coastguard Worker std::unique_ptr<Message> UnpackIfAny(const Message& message) {
399*fd525a9cSAndroid Build Coastguard Worker   if (const Any* any = CastToAny(&message)) return UnpackAny(*any);
400*fd525a9cSAndroid Build Coastguard Worker   return {};
401*fd525a9cSAndroid Build Coastguard Worker }
402*fd525a9cSAndroid Build Coastguard Worker 
UnpackAny(const Message & message,UnpackedAny * result)403*fd525a9cSAndroid Build Coastguard Worker void UnpackAny(const Message& message, UnpackedAny* result) {
404*fd525a9cSAndroid Build Coastguard Worker   if (std::unique_ptr<Message> any = UnpackIfAny(message)) {
405*fd525a9cSAndroid Build Coastguard Worker     UnpackAny(*any, result);
406*fd525a9cSAndroid Build Coastguard Worker     result->emplace(&message, std::move(any));
407*fd525a9cSAndroid Build Coastguard Worker     return;
408*fd525a9cSAndroid Build Coastguard Worker   }
409*fd525a9cSAndroid Build Coastguard Worker 
410*fd525a9cSAndroid Build Coastguard Worker   const Descriptor* descriptor = message.GetDescriptor();
411*fd525a9cSAndroid Build Coastguard Worker   const Reflection* reflection = message.GetReflection();
412*fd525a9cSAndroid Build Coastguard Worker 
413*fd525a9cSAndroid Build Coastguard Worker   for (int i = 0; i < descriptor->field_count(); ++i) {
414*fd525a9cSAndroid Build Coastguard Worker     const FieldDescriptor* field = descriptor->field(i);
415*fd525a9cSAndroid Build Coastguard Worker     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
416*fd525a9cSAndroid Build Coastguard Worker       if (field->is_repeated()) {
417*fd525a9cSAndroid Build Coastguard Worker         const int field_size = reflection->FieldSize(message, field);
418*fd525a9cSAndroid Build Coastguard Worker         for (int j = 0; j < field_size; ++j) {
419*fd525a9cSAndroid Build Coastguard Worker           UnpackAny(reflection->GetRepeatedMessage(message, field, j), result);
420*fd525a9cSAndroid Build Coastguard Worker         }
421*fd525a9cSAndroid Build Coastguard Worker       } else if (reflection->HasField(message, field)) {
422*fd525a9cSAndroid Build Coastguard Worker         UnpackAny(reflection->GetMessage(message, field), result);
423*fd525a9cSAndroid Build Coastguard Worker       }
424*fd525a9cSAndroid Build Coastguard Worker     }
425*fd525a9cSAndroid Build Coastguard Worker   }
426*fd525a9cSAndroid Build Coastguard Worker }
427*fd525a9cSAndroid Build Coastguard Worker 
428*fd525a9cSAndroid Build Coastguard Worker class PostProcessing {
429*fd525a9cSAndroid Build Coastguard Worker  public:
430*fd525a9cSAndroid Build Coastguard Worker   using PostProcessors =
431*fd525a9cSAndroid Build Coastguard Worker       std::unordered_multimap<const Descriptor*, Mutator::PostProcess>;
432*fd525a9cSAndroid Build Coastguard Worker 
PostProcessing(bool keep_initialized,const PostProcessors & post_processors,const UnpackedAny & any,RandomEngine * random)433*fd525a9cSAndroid Build Coastguard Worker   PostProcessing(bool keep_initialized, const PostProcessors& post_processors,
434*fd525a9cSAndroid Build Coastguard Worker                  const UnpackedAny& any, RandomEngine* random)
435*fd525a9cSAndroid Build Coastguard Worker       : keep_initialized_(keep_initialized),
436*fd525a9cSAndroid Build Coastguard Worker         post_processors_(post_processors),
437*fd525a9cSAndroid Build Coastguard Worker         any_(any),
438*fd525a9cSAndroid Build Coastguard Worker         random_(random) {}
439*fd525a9cSAndroid Build Coastguard Worker 
Run(Message * message,int max_depth)440*fd525a9cSAndroid Build Coastguard Worker   void Run(Message* message, int max_depth) {
441*fd525a9cSAndroid Build Coastguard Worker     --max_depth;
442*fd525a9cSAndroid Build Coastguard Worker     const Descriptor* descriptor = message->GetDescriptor();
443*fd525a9cSAndroid Build Coastguard Worker 
444*fd525a9cSAndroid Build Coastguard Worker     // Apply custom mutators in nested messages before packing any.
445*fd525a9cSAndroid Build Coastguard Worker     const Reflection* reflection = message->GetReflection();
446*fd525a9cSAndroid Build Coastguard Worker     for (int i = 0; i < descriptor->field_count(); i++) {
447*fd525a9cSAndroid Build Coastguard Worker       const FieldDescriptor* field = descriptor->field(i);
448*fd525a9cSAndroid Build Coastguard Worker       if (keep_initialized_ &&
449*fd525a9cSAndroid Build Coastguard Worker           (field->is_required() || descriptor->options().map_entry()) &&
450*fd525a9cSAndroid Build Coastguard Worker           !reflection->HasField(*message, field)) {
451*fd525a9cSAndroid Build Coastguard Worker         CreateDefaultField()(FieldInstance(message, field));
452*fd525a9cSAndroid Build Coastguard Worker       }
453*fd525a9cSAndroid Build Coastguard Worker 
454*fd525a9cSAndroid Build Coastguard Worker       if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
455*fd525a9cSAndroid Build Coastguard Worker 
456*fd525a9cSAndroid Build Coastguard Worker       if (max_depth < 0 && !field->is_required()) {
457*fd525a9cSAndroid Build Coastguard Worker         // Clear deep optional fields to avoid stack overflow.
458*fd525a9cSAndroid Build Coastguard Worker         reflection->ClearField(message, field);
459*fd525a9cSAndroid Build Coastguard Worker         if (field->is_repeated())
460*fd525a9cSAndroid Build Coastguard Worker           assert(!reflection->FieldSize(*message, field));
461*fd525a9cSAndroid Build Coastguard Worker         else
462*fd525a9cSAndroid Build Coastguard Worker           assert(!reflection->HasField(*message, field));
463*fd525a9cSAndroid Build Coastguard Worker         continue;
464*fd525a9cSAndroid Build Coastguard Worker       }
465*fd525a9cSAndroid Build Coastguard Worker 
466*fd525a9cSAndroid Build Coastguard Worker       if (field->is_repeated()) {
467*fd525a9cSAndroid Build Coastguard Worker         const int field_size = reflection->FieldSize(*message, field);
468*fd525a9cSAndroid Build Coastguard Worker         for (int j = 0; j < field_size; ++j) {
469*fd525a9cSAndroid Build Coastguard Worker           Message* nested_message =
470*fd525a9cSAndroid Build Coastguard Worker               reflection->MutableRepeatedMessage(message, field, j);
471*fd525a9cSAndroid Build Coastguard Worker           Run(nested_message, max_depth);
472*fd525a9cSAndroid Build Coastguard Worker         }
473*fd525a9cSAndroid Build Coastguard Worker       } else if (reflection->HasField(*message, field)) {
474*fd525a9cSAndroid Build Coastguard Worker         Message* nested_message = reflection->MutableMessage(message, field);
475*fd525a9cSAndroid Build Coastguard Worker         Run(nested_message, max_depth);
476*fd525a9cSAndroid Build Coastguard Worker       }
477*fd525a9cSAndroid Build Coastguard Worker     }
478*fd525a9cSAndroid Build Coastguard Worker 
479*fd525a9cSAndroid Build Coastguard Worker     if (Any* any = CastToAny(message)) {
480*fd525a9cSAndroid Build Coastguard Worker       if (max_depth < 0) {
481*fd525a9cSAndroid Build Coastguard Worker         // Clear deep Any fields to avoid stack overflow.
482*fd525a9cSAndroid Build Coastguard Worker         any->Clear();
483*fd525a9cSAndroid Build Coastguard Worker       } else {
484*fd525a9cSAndroid Build Coastguard Worker         auto It = any_.find(message);
485*fd525a9cSAndroid Build Coastguard Worker         if (It != any_.end()) {
486*fd525a9cSAndroid Build Coastguard Worker           Run(It->second.get(), max_depth);
487*fd525a9cSAndroid Build Coastguard Worker           std::string value;
488*fd525a9cSAndroid Build Coastguard Worker           It->second->SerializePartialToString(&value);
489*fd525a9cSAndroid Build Coastguard Worker           *any->mutable_value() = value;
490*fd525a9cSAndroid Build Coastguard Worker         }
491*fd525a9cSAndroid Build Coastguard Worker       }
492*fd525a9cSAndroid Build Coastguard Worker     }
493*fd525a9cSAndroid Build Coastguard Worker 
494*fd525a9cSAndroid Build Coastguard Worker     // Call user callback after message trimmed, initialized and packed.
495*fd525a9cSAndroid Build Coastguard Worker     auto range = post_processors_.equal_range(descriptor);
496*fd525a9cSAndroid Build Coastguard Worker     for (auto it = range.first; it != range.second; ++it)
497*fd525a9cSAndroid Build Coastguard Worker       it->second(message, (*random_)());
498*fd525a9cSAndroid Build Coastguard Worker   }
499*fd525a9cSAndroid Build Coastguard Worker 
500*fd525a9cSAndroid Build Coastguard Worker  private:
501*fd525a9cSAndroid Build Coastguard Worker   bool keep_initialized_;
502*fd525a9cSAndroid Build Coastguard Worker   const PostProcessors& post_processors_;
503*fd525a9cSAndroid Build Coastguard Worker   const UnpackedAny& any_;
504*fd525a9cSAndroid Build Coastguard Worker   RandomEngine* random_;
505*fd525a9cSAndroid Build Coastguard Worker };
506*fd525a9cSAndroid Build Coastguard Worker 
507*fd525a9cSAndroid Build Coastguard Worker }  // namespace
508*fd525a9cSAndroid Build Coastguard Worker 
509*fd525a9cSAndroid Build Coastguard Worker class FieldMutator {
510*fd525a9cSAndroid Build Coastguard Worker  public:
FieldMutator(int size_increase_hint,bool enforce_changes,bool enforce_utf8_strings,const ConstMessages & sources,Mutator * mutator)511*fd525a9cSAndroid Build Coastguard Worker   FieldMutator(int size_increase_hint, bool enforce_changes,
512*fd525a9cSAndroid Build Coastguard Worker                bool enforce_utf8_strings, const ConstMessages& sources,
513*fd525a9cSAndroid Build Coastguard Worker                Mutator* mutator)
514*fd525a9cSAndroid Build Coastguard Worker       : size_increase_hint_(size_increase_hint),
515*fd525a9cSAndroid Build Coastguard Worker         enforce_changes_(enforce_changes),
516*fd525a9cSAndroid Build Coastguard Worker         enforce_utf8_strings_(enforce_utf8_strings),
517*fd525a9cSAndroid Build Coastguard Worker         sources_(sources),
518*fd525a9cSAndroid Build Coastguard Worker         mutator_(mutator) {}
519*fd525a9cSAndroid Build Coastguard Worker 
Mutate(int32_t * value) const520*fd525a9cSAndroid Build Coastguard Worker   void Mutate(int32_t* value) const {
521*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateInt32, mutator_, _1));
522*fd525a9cSAndroid Build Coastguard Worker   }
523*fd525a9cSAndroid Build Coastguard Worker 
Mutate(int64_t * value) const524*fd525a9cSAndroid Build Coastguard Worker   void Mutate(int64_t* value) const {
525*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateInt64, mutator_, _1));
526*fd525a9cSAndroid Build Coastguard Worker   }
527*fd525a9cSAndroid Build Coastguard Worker 
Mutate(uint32_t * value) const528*fd525a9cSAndroid Build Coastguard Worker   void Mutate(uint32_t* value) const {
529*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateUInt32, mutator_, _1));
530*fd525a9cSAndroid Build Coastguard Worker   }
531*fd525a9cSAndroid Build Coastguard Worker 
Mutate(uint64_t * value) const532*fd525a9cSAndroid Build Coastguard Worker   void Mutate(uint64_t* value) const {
533*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateUInt64, mutator_, _1));
534*fd525a9cSAndroid Build Coastguard Worker   }
535*fd525a9cSAndroid Build Coastguard Worker 
Mutate(float * value) const536*fd525a9cSAndroid Build Coastguard Worker   void Mutate(float* value) const {
537*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateFloat, mutator_, _1));
538*fd525a9cSAndroid Build Coastguard Worker   }
539*fd525a9cSAndroid Build Coastguard Worker 
Mutate(double * value) const540*fd525a9cSAndroid Build Coastguard Worker   void Mutate(double* value) const {
541*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateDouble, mutator_, _1));
542*fd525a9cSAndroid Build Coastguard Worker   }
543*fd525a9cSAndroid Build Coastguard Worker 
Mutate(bool * value) const544*fd525a9cSAndroid Build Coastguard Worker   void Mutate(bool* value) const {
545*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(value, std::bind(&Mutator::MutateBool, mutator_, _1));
546*fd525a9cSAndroid Build Coastguard Worker   }
547*fd525a9cSAndroid Build Coastguard Worker 
Mutate(FieldInstance::Enum * value) const548*fd525a9cSAndroid Build Coastguard Worker   void Mutate(FieldInstance::Enum* value) const {
549*fd525a9cSAndroid Build Coastguard Worker     RepeatMutate(&value->index,
550*fd525a9cSAndroid Build Coastguard Worker                  std::bind(&Mutator::MutateEnum, mutator_, _1, value->count));
551*fd525a9cSAndroid Build Coastguard Worker     assert(value->index < value->count);
552*fd525a9cSAndroid Build Coastguard Worker   }
553*fd525a9cSAndroid Build Coastguard Worker 
Mutate(std::string * value) const554*fd525a9cSAndroid Build Coastguard Worker   void Mutate(std::string* value) const {
555*fd525a9cSAndroid Build Coastguard Worker     if (enforce_utf8_strings_) {
556*fd525a9cSAndroid Build Coastguard Worker       RepeatMutate(value, std::bind(&Mutator::MutateUtf8String, mutator_, _1,
557*fd525a9cSAndroid Build Coastguard Worker                                     size_increase_hint_));
558*fd525a9cSAndroid Build Coastguard Worker     } else {
559*fd525a9cSAndroid Build Coastguard Worker       RepeatMutate(value, std::bind(&Mutator::MutateString, mutator_, _1,
560*fd525a9cSAndroid Build Coastguard Worker                                     size_increase_hint_));
561*fd525a9cSAndroid Build Coastguard Worker     }
562*fd525a9cSAndroid Build Coastguard Worker   }
563*fd525a9cSAndroid Build Coastguard Worker 
Mutate(std::unique_ptr<Message> * message) const564*fd525a9cSAndroid Build Coastguard Worker   void Mutate(std::unique_ptr<Message>* message) const {
565*fd525a9cSAndroid Build Coastguard Worker     assert(!enforce_changes_);
566*fd525a9cSAndroid Build Coastguard Worker     assert(*message);
567*fd525a9cSAndroid Build Coastguard Worker     if (GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_))
568*fd525a9cSAndroid Build Coastguard Worker       return;
569*fd525a9cSAndroid Build Coastguard Worker     mutator_->MutateImpl(sources_, {message->get()}, false,
570*fd525a9cSAndroid Build Coastguard Worker                          size_increase_hint_);
571*fd525a9cSAndroid Build Coastguard Worker   }
572*fd525a9cSAndroid Build Coastguard Worker 
573*fd525a9cSAndroid Build Coastguard Worker  private:
574*fd525a9cSAndroid Build Coastguard Worker   template <class T, class F>
RepeatMutate(T * value,F mutate) const575*fd525a9cSAndroid Build Coastguard Worker   void RepeatMutate(T* value, F mutate) const {
576*fd525a9cSAndroid Build Coastguard Worker     if (!enforce_changes_ &&
577*fd525a9cSAndroid Build Coastguard Worker         GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_)) {
578*fd525a9cSAndroid Build Coastguard Worker       return;
579*fd525a9cSAndroid Build Coastguard Worker     }
580*fd525a9cSAndroid Build Coastguard Worker     T tmp = *value;
581*fd525a9cSAndroid Build Coastguard Worker     for (int i = 0; i < 10; ++i) {
582*fd525a9cSAndroid Build Coastguard Worker       *value = mutate(*value);
583*fd525a9cSAndroid Build Coastguard Worker       if (!enforce_changes_ || *value != tmp) return;
584*fd525a9cSAndroid Build Coastguard Worker     }
585*fd525a9cSAndroid Build Coastguard Worker   }
586*fd525a9cSAndroid Build Coastguard Worker 
587*fd525a9cSAndroid Build Coastguard Worker   int size_increase_hint_;
588*fd525a9cSAndroid Build Coastguard Worker   size_t enforce_changes_;
589*fd525a9cSAndroid Build Coastguard Worker   bool enforce_utf8_strings_;
590*fd525a9cSAndroid Build Coastguard Worker   const ConstMessages& sources_;
591*fd525a9cSAndroid Build Coastguard Worker   Mutator* mutator_;
592*fd525a9cSAndroid Build Coastguard Worker };
593*fd525a9cSAndroid Build Coastguard Worker 
594*fd525a9cSAndroid Build Coastguard Worker namespace {
595*fd525a9cSAndroid Build Coastguard Worker 
596*fd525a9cSAndroid Build Coastguard Worker struct MutateField : public FieldFunction<MutateField> {
597*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0211::MutateField598*fd525a9cSAndroid Build Coastguard Worker   void ForType(const FieldInstance& field, int size_increase_hint,
599*fd525a9cSAndroid Build Coastguard Worker                const ConstMessages& sources, Mutator* mutator) const {
600*fd525a9cSAndroid Build Coastguard Worker     T value;
601*fd525a9cSAndroid Build Coastguard Worker     field.Load(&value);
602*fd525a9cSAndroid Build Coastguard Worker     FieldMutator(size_increase_hint, true, field.EnforceUtf8(), sources,
603*fd525a9cSAndroid Build Coastguard Worker                  mutator)
604*fd525a9cSAndroid Build Coastguard Worker         .Mutate(&value);
605*fd525a9cSAndroid Build Coastguard Worker     field.Store(value);
606*fd525a9cSAndroid Build Coastguard Worker   }
607*fd525a9cSAndroid Build Coastguard Worker };
608*fd525a9cSAndroid Build Coastguard Worker 
609*fd525a9cSAndroid Build Coastguard Worker struct CreateField : public FieldFunction<CreateField> {
610*fd525a9cSAndroid Build Coastguard Worker  public:
611*fd525a9cSAndroid Build Coastguard Worker   template <class T>
ForTypeprotobuf_mutator::__anonab369fae0211::CreateField612*fd525a9cSAndroid Build Coastguard Worker   void ForType(const FieldInstance& field, int size_increase_hint,
613*fd525a9cSAndroid Build Coastguard Worker                const ConstMessages& sources, Mutator* mutator) const {
614*fd525a9cSAndroid Build Coastguard Worker     T value;
615*fd525a9cSAndroid Build Coastguard Worker     field.GetDefault(&value);
616*fd525a9cSAndroid Build Coastguard Worker     FieldMutator field_mutator(size_increase_hint,
617*fd525a9cSAndroid Build Coastguard Worker                                false /* defaults could be useful */,
618*fd525a9cSAndroid Build Coastguard Worker                                field.EnforceUtf8(), sources, mutator);
619*fd525a9cSAndroid Build Coastguard Worker     field_mutator.Mutate(&value);
620*fd525a9cSAndroid Build Coastguard Worker     field.Create(value);
621*fd525a9cSAndroid Build Coastguard Worker   }
622*fd525a9cSAndroid Build Coastguard Worker };
623*fd525a9cSAndroid Build Coastguard Worker 
624*fd525a9cSAndroid Build Coastguard Worker }  // namespace
625*fd525a9cSAndroid Build Coastguard Worker 
Seed(uint32_t value)626*fd525a9cSAndroid Build Coastguard Worker void Mutator::Seed(uint32_t value) { random_.seed(value); }
627*fd525a9cSAndroid Build Coastguard Worker 
Fix(Message * message)628*fd525a9cSAndroid Build Coastguard Worker void Mutator::Fix(Message* message) {
629*fd525a9cSAndroid Build Coastguard Worker   UnpackedAny any;
630*fd525a9cSAndroid Build Coastguard Worker   UnpackAny(*message, &any);
631*fd525a9cSAndroid Build Coastguard Worker 
632*fd525a9cSAndroid Build Coastguard Worker   PostProcessing(keep_initialized_, post_processors_, any, &random_)
633*fd525a9cSAndroid Build Coastguard Worker       .Run(message, kMaxInitializeDepth);
634*fd525a9cSAndroid Build Coastguard Worker   assert(IsInitialized(*message));
635*fd525a9cSAndroid Build Coastguard Worker }
636*fd525a9cSAndroid Build Coastguard Worker 
Mutate(Message * message,size_t max_size_hint)637*fd525a9cSAndroid Build Coastguard Worker void Mutator::Mutate(Message* message, size_t max_size_hint) {
638*fd525a9cSAndroid Build Coastguard Worker   UnpackedAny any;
639*fd525a9cSAndroid Build Coastguard Worker   UnpackAny(*message, &any);
640*fd525a9cSAndroid Build Coastguard Worker 
641*fd525a9cSAndroid Build Coastguard Worker   Messages messages;
642*fd525a9cSAndroid Build Coastguard Worker   messages.reserve(any.size() + 1);
643*fd525a9cSAndroid Build Coastguard Worker   messages.push_back(message);
644*fd525a9cSAndroid Build Coastguard Worker   for (const auto& kv : any) messages.push_back(kv.second.get());
645*fd525a9cSAndroid Build Coastguard Worker 
646*fd525a9cSAndroid Build Coastguard Worker   ConstMessages sources(messages.begin(), messages.end());
647*fd525a9cSAndroid Build Coastguard Worker   MutateImpl(sources, messages, false,
648*fd525a9cSAndroid Build Coastguard Worker              static_cast<int>(max_size_hint) -
649*fd525a9cSAndroid Build Coastguard Worker                  static_cast<int>(message->ByteSizeLong()));
650*fd525a9cSAndroid Build Coastguard Worker 
651*fd525a9cSAndroid Build Coastguard Worker   PostProcessing(keep_initialized_, post_processors_, any, &random_)
652*fd525a9cSAndroid Build Coastguard Worker       .Run(message, kMaxInitializeDepth);
653*fd525a9cSAndroid Build Coastguard Worker   assert(IsInitialized(*message));
654*fd525a9cSAndroid Build Coastguard Worker }
655*fd525a9cSAndroid Build Coastguard Worker 
CrossOver(const Message & message1,Message * message2,size_t max_size_hint)656*fd525a9cSAndroid Build Coastguard Worker void Mutator::CrossOver(const Message& message1, Message* message2,
657*fd525a9cSAndroid Build Coastguard Worker                         size_t max_size_hint) {
658*fd525a9cSAndroid Build Coastguard Worker   UnpackedAny any;
659*fd525a9cSAndroid Build Coastguard Worker   UnpackAny(*message2, &any);
660*fd525a9cSAndroid Build Coastguard Worker 
661*fd525a9cSAndroid Build Coastguard Worker   Messages messages;
662*fd525a9cSAndroid Build Coastguard Worker   messages.reserve(any.size() + 1);
663*fd525a9cSAndroid Build Coastguard Worker   messages.push_back(message2);
664*fd525a9cSAndroid Build Coastguard Worker   for (auto& kv : any) messages.push_back(kv.second.get());
665*fd525a9cSAndroid Build Coastguard Worker 
666*fd525a9cSAndroid Build Coastguard Worker   UnpackAny(message1, &any);
667*fd525a9cSAndroid Build Coastguard Worker 
668*fd525a9cSAndroid Build Coastguard Worker   ConstMessages sources;
669*fd525a9cSAndroid Build Coastguard Worker   sources.reserve(any.size() + 2);
670*fd525a9cSAndroid Build Coastguard Worker   sources.push_back(&message1);
671*fd525a9cSAndroid Build Coastguard Worker   sources.push_back(message2);
672*fd525a9cSAndroid Build Coastguard Worker   for (const auto& kv : any) sources.push_back(kv.second.get());
673*fd525a9cSAndroid Build Coastguard Worker 
674*fd525a9cSAndroid Build Coastguard Worker   MutateImpl(sources, messages, true,
675*fd525a9cSAndroid Build Coastguard Worker              static_cast<int>(max_size_hint) -
676*fd525a9cSAndroid Build Coastguard Worker                  static_cast<int>(message2->ByteSizeLong()));
677*fd525a9cSAndroid Build Coastguard Worker 
678*fd525a9cSAndroid Build Coastguard Worker   PostProcessing(keep_initialized_, post_processors_, any, &random_)
679*fd525a9cSAndroid Build Coastguard Worker       .Run(message2, kMaxInitializeDepth);
680*fd525a9cSAndroid Build Coastguard Worker   assert(IsInitialized(*message2));
681*fd525a9cSAndroid Build Coastguard Worker }
682*fd525a9cSAndroid Build Coastguard Worker 
RegisterPostProcessor(const Descriptor * desc,PostProcess callback)683*fd525a9cSAndroid Build Coastguard Worker void Mutator::RegisterPostProcessor(const Descriptor* desc,
684*fd525a9cSAndroid Build Coastguard Worker                                     PostProcess callback) {
685*fd525a9cSAndroid Build Coastguard Worker   post_processors_.emplace(desc, callback);
686*fd525a9cSAndroid Build Coastguard Worker }
687*fd525a9cSAndroid Build Coastguard Worker 
MutateImpl(const ConstMessages & sources,const Messages & messages,bool copy_clone_only,int size_increase_hint)688*fd525a9cSAndroid Build Coastguard Worker bool Mutator::MutateImpl(const ConstMessages& sources, const Messages& messages,
689*fd525a9cSAndroid Build Coastguard Worker                          bool copy_clone_only, int size_increase_hint) {
690*fd525a9cSAndroid Build Coastguard Worker   MutationBitset mutations;
691*fd525a9cSAndroid Build Coastguard Worker   if (copy_clone_only) {
692*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(Mutation::Copy)] = true;
693*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(Mutation::Clone)] = true;
694*fd525a9cSAndroid Build Coastguard Worker   } else if (size_increase_hint <= 16) {
695*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(Mutation::Delete)] = true;
696*fd525a9cSAndroid Build Coastguard Worker   } else {
697*fd525a9cSAndroid Build Coastguard Worker     mutations.set();
698*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(Mutation::Copy)] = false;
699*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(Mutation::Clone)] = false;
700*fd525a9cSAndroid Build Coastguard Worker   }
701*fd525a9cSAndroid Build Coastguard Worker   while (mutations.any()) {
702*fd525a9cSAndroid Build Coastguard Worker     MutationSampler mutation(keep_initialized_, mutations, &random_);
703*fd525a9cSAndroid Build Coastguard Worker     for (Message* message : messages) mutation.Sample(message);
704*fd525a9cSAndroid Build Coastguard Worker 
705*fd525a9cSAndroid Build Coastguard Worker     switch (mutation.mutation()) {
706*fd525a9cSAndroid Build Coastguard Worker       case Mutation::None:
707*fd525a9cSAndroid Build Coastguard Worker         return true;
708*fd525a9cSAndroid Build Coastguard Worker       case Mutation::Add:
709*fd525a9cSAndroid Build Coastguard Worker         CreateField()(mutation.field(), size_increase_hint, sources, this);
710*fd525a9cSAndroid Build Coastguard Worker         return true;
711*fd525a9cSAndroid Build Coastguard Worker       case Mutation::Mutate:
712*fd525a9cSAndroid Build Coastguard Worker         MutateField()(mutation.field(), size_increase_hint, sources, this);
713*fd525a9cSAndroid Build Coastguard Worker         return true;
714*fd525a9cSAndroid Build Coastguard Worker       case Mutation::Delete:
715*fd525a9cSAndroid Build Coastguard Worker         DeleteField()(mutation.field());
716*fd525a9cSAndroid Build Coastguard Worker         return true;
717*fd525a9cSAndroid Build Coastguard Worker       case Mutation::Clone: {
718*fd525a9cSAndroid Build Coastguard Worker         CreateDefaultField()(mutation.field());
719*fd525a9cSAndroid Build Coastguard Worker         DataSourceSampler source_sampler(mutation.field(), &random_,
720*fd525a9cSAndroid Build Coastguard Worker                                          size_increase_hint);
721*fd525a9cSAndroid Build Coastguard Worker         for (const Message* source : sources) source_sampler.Sample(*source);
722*fd525a9cSAndroid Build Coastguard Worker         if (source_sampler.IsEmpty()) {
723*fd525a9cSAndroid Build Coastguard Worker           if (!IsProto3SimpleField(*mutation.field().descriptor()))
724*fd525a9cSAndroid Build Coastguard Worker             return true;  // CreateField is enough for proto2.
725*fd525a9cSAndroid Build Coastguard Worker           break;
726*fd525a9cSAndroid Build Coastguard Worker         }
727*fd525a9cSAndroid Build Coastguard Worker         CopyField()(source_sampler.field(), mutation.field());
728*fd525a9cSAndroid Build Coastguard Worker         return true;
729*fd525a9cSAndroid Build Coastguard Worker       }
730*fd525a9cSAndroid Build Coastguard Worker       case Mutation::Copy: {
731*fd525a9cSAndroid Build Coastguard Worker         DataSourceSampler source_sampler(mutation.field(), &random_,
732*fd525a9cSAndroid Build Coastguard Worker                                          size_increase_hint);
733*fd525a9cSAndroid Build Coastguard Worker         for (const Message* source : sources) source_sampler.Sample(*source);
734*fd525a9cSAndroid Build Coastguard Worker         if (source_sampler.IsEmpty()) break;
735*fd525a9cSAndroid Build Coastguard Worker         CopyField()(source_sampler.field(), mutation.field());
736*fd525a9cSAndroid Build Coastguard Worker         return true;
737*fd525a9cSAndroid Build Coastguard Worker       }
738*fd525a9cSAndroid Build Coastguard Worker       default:
739*fd525a9cSAndroid Build Coastguard Worker         assert(false && "unexpected mutation");
740*fd525a9cSAndroid Build Coastguard Worker         return false;
741*fd525a9cSAndroid Build Coastguard Worker     }
742*fd525a9cSAndroid Build Coastguard Worker 
743*fd525a9cSAndroid Build Coastguard Worker     // Don't try same mutation next time.
744*fd525a9cSAndroid Build Coastguard Worker     mutations[static_cast<size_t>(mutation.mutation())] = false;
745*fd525a9cSAndroid Build Coastguard Worker   }
746*fd525a9cSAndroid Build Coastguard Worker   return false;
747*fd525a9cSAndroid Build Coastguard Worker }
748*fd525a9cSAndroid Build Coastguard Worker 
MutateInt32(int32_t value)749*fd525a9cSAndroid Build Coastguard Worker int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, &random_); }
750*fd525a9cSAndroid Build Coastguard Worker 
MutateInt64(int64_t value)751*fd525a9cSAndroid Build Coastguard Worker int64_t Mutator::MutateInt64(int64_t value) { return FlipBit(value, &random_); }
752*fd525a9cSAndroid Build Coastguard Worker 
MutateUInt32(uint32_t value)753*fd525a9cSAndroid Build Coastguard Worker uint32_t Mutator::MutateUInt32(uint32_t value) {
754*fd525a9cSAndroid Build Coastguard Worker   return FlipBit(value, &random_);
755*fd525a9cSAndroid Build Coastguard Worker }
756*fd525a9cSAndroid Build Coastguard Worker 
MutateUInt64(uint64_t value)757*fd525a9cSAndroid Build Coastguard Worker uint64_t Mutator::MutateUInt64(uint64_t value) {
758*fd525a9cSAndroid Build Coastguard Worker   return FlipBit(value, &random_);
759*fd525a9cSAndroid Build Coastguard Worker }
760*fd525a9cSAndroid Build Coastguard Worker 
MutateFloat(float value)761*fd525a9cSAndroid Build Coastguard Worker float Mutator::MutateFloat(float value) { return FlipBit(value, &random_); }
762*fd525a9cSAndroid Build Coastguard Worker 
MutateDouble(double value)763*fd525a9cSAndroid Build Coastguard Worker double Mutator::MutateDouble(double value) { return FlipBit(value, &random_); }
764*fd525a9cSAndroid Build Coastguard Worker 
MutateBool(bool value)765*fd525a9cSAndroid Build Coastguard Worker bool Mutator::MutateBool(bool value) { return !value; }
766*fd525a9cSAndroid Build Coastguard Worker 
MutateEnum(size_t index,size_t item_count)767*fd525a9cSAndroid Build Coastguard Worker size_t Mutator::MutateEnum(size_t index, size_t item_count) {
768*fd525a9cSAndroid Build Coastguard Worker   if (item_count <= 1) return 0;
769*fd525a9cSAndroid Build Coastguard Worker   return (index + 1 + GetRandomIndex(&random_, item_count - 1)) % item_count;
770*fd525a9cSAndroid Build Coastguard Worker }
771*fd525a9cSAndroid Build Coastguard Worker 
MutateString(const std::string & value,int size_increase_hint)772*fd525a9cSAndroid Build Coastguard Worker std::string Mutator::MutateString(const std::string& value,
773*fd525a9cSAndroid Build Coastguard Worker                                   int size_increase_hint) {
774*fd525a9cSAndroid Build Coastguard Worker   std::string result = value;
775*fd525a9cSAndroid Build Coastguard Worker 
776*fd525a9cSAndroid Build Coastguard Worker   while (!result.empty() && GetRandomBool(&random_)) {
777*fd525a9cSAndroid Build Coastguard Worker     result.erase(GetRandomIndex(&random_, result.size()), 1);
778*fd525a9cSAndroid Build Coastguard Worker   }
779*fd525a9cSAndroid Build Coastguard Worker 
780*fd525a9cSAndroid Build Coastguard Worker   while (size_increase_hint > 0 &&
781*fd525a9cSAndroid Build Coastguard Worker          result.size() < static_cast<size_t>(size_increase_hint) &&
782*fd525a9cSAndroid Build Coastguard Worker          GetRandomBool(&random_)) {
783*fd525a9cSAndroid Build Coastguard Worker     size_t index = GetRandomIndex(&random_, result.size() + 1);
784*fd525a9cSAndroid Build Coastguard Worker     result.insert(result.begin() + index, GetRandomIndex(&random_, 1 << 8));
785*fd525a9cSAndroid Build Coastguard Worker   }
786*fd525a9cSAndroid Build Coastguard Worker 
787*fd525a9cSAndroid Build Coastguard Worker   if (result != value) return result;
788*fd525a9cSAndroid Build Coastguard Worker 
789*fd525a9cSAndroid Build Coastguard Worker   if (result.empty()) {
790*fd525a9cSAndroid Build Coastguard Worker     result.push_back(GetRandomIndex(&random_, 1 << 8));
791*fd525a9cSAndroid Build Coastguard Worker     return result;
792*fd525a9cSAndroid Build Coastguard Worker   }
793*fd525a9cSAndroid Build Coastguard Worker 
794*fd525a9cSAndroid Build Coastguard Worker   if (!result.empty())
795*fd525a9cSAndroid Build Coastguard Worker     FlipBit(result.size(), reinterpret_cast<uint8_t*>(&result[0]), &random_);
796*fd525a9cSAndroid Build Coastguard Worker   return result;
797*fd525a9cSAndroid Build Coastguard Worker }
798*fd525a9cSAndroid Build Coastguard Worker 
MutateUtf8String(const std::string & value,int size_increase_hint)799*fd525a9cSAndroid Build Coastguard Worker std::string Mutator::MutateUtf8String(const std::string& value,
800*fd525a9cSAndroid Build Coastguard Worker                                       int size_increase_hint) {
801*fd525a9cSAndroid Build Coastguard Worker   std::string str = MutateString(value, size_increase_hint);
802*fd525a9cSAndroid Build Coastguard Worker   FixUtf8String(&str, &random_);
803*fd525a9cSAndroid Build Coastguard Worker   return str;
804*fd525a9cSAndroid Build Coastguard Worker }
805*fd525a9cSAndroid Build Coastguard Worker 
IsInitialized(const Message & message) const806*fd525a9cSAndroid Build Coastguard Worker bool Mutator::IsInitialized(const Message& message) const {
807*fd525a9cSAndroid Build Coastguard Worker   if (!keep_initialized_ || message.IsInitialized()) return true;
808*fd525a9cSAndroid Build Coastguard Worker   std::cerr << "Uninitialized: " << message.DebugString() << "\n";
809*fd525a9cSAndroid Build Coastguard Worker   return false;
810*fd525a9cSAndroid Build Coastguard Worker }
811*fd525a9cSAndroid Build Coastguard Worker 
812*fd525a9cSAndroid Build Coastguard Worker }  // namespace protobuf_mutator
813