~ubuntu-branches/debian/squeeze/protobuf/squeeze

« back to all changes in this revision

Viewing changes to src/google/protobuf/text_format.cc

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-06-02 16:19:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090602161900-vm176i3ryt35yk91
Tags: 2.0.3-2.2
* Non-maintainer upload.
* Fix FTBFS from -2.1: don't fail when we can't clean up the java build,
  such as when openjdk isn't installed.
* Disable parallel builds, because libtool is made of fail (if binary-arch
  and build-indep run concurrently, we relink a library while it's being
  used; that doesn't work so well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.
 
2
// Copyright 2008 Google Inc.  All rights reserved.
3
3
// http://code.google.com/p/protobuf/
4
4
//
5
 
// Licensed under the Apache License, Version 2.0 (the "License");
6
 
// you may not use this file except in compliance with the License.
7
 
// You may obtain a copy of the License at
8
 
//
9
 
//      http://www.apache.org/licenses/LICENSE-2.0
10
 
//
11
 
// Unless required by applicable law or agreed to in writing, software
12
 
// distributed under the License is distributed on an "AS IS" BASIS,
13
 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
// See the License for the specific language governing permissions and
15
 
// limitations under the License.
 
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.
16
30
 
17
31
// Author: jschorr@google.com (Joseph Schorr)
18
32
//  Based on original Protocol Buffers design by
20
34
 
21
35
#include <float.h>
22
36
#include <math.h>
 
37
#include <stdio.h>
23
38
#include <stack>
24
39
#include <limits>
25
40
 
51
66
  //   DebugString() and munging the result.
52
67
  string result = DebugString();
53
68
 
54
 
  // Replace each contiguous range of whitespace (including newlines) with a
55
 
  // single space.
56
 
  for (int i = 0; i < result.size(); i++) {
57
 
    int pos = i;
58
 
    while (isspace(result[pos])) ++pos;
59
 
    if (pos > i) result.replace(i, pos - i, " ");
60
 
  }
 
69
  // Replace each contiguous range of whitespace (including newlines, and
 
70
  // starting with a newline) with a single space.
 
71
  int out = 0;
 
72
  for (int i = 0; i < result.size(); ++i) {
 
73
    if (result[i] != '\n') {
 
74
      result[out++] = result[i];
 
75
    } else {
 
76
      while (i < result.size() && isspace(result[i])) ++i;
 
77
      --i;
 
78
      result[out++] = ' ';
 
79
    }
 
80
  }
 
81
  // Remove trailing space, if there is one.
 
82
  if (out > 0 && isspace(result[out - 1])) {
 
83
    --out;
 
84
  }
 
85
  result.resize(out);
61
86
 
62
87
  return result;
63
88
}
78
103
// returning false. Borrowed from parser.cc (Thanks Kenton!).
79
104
#define DO(STATEMENT) if (STATEMENT) {} else return false
80
105
 
81
 
class TextFormat::ParserImpl {
 
106
class TextFormat::Parser::ParserImpl {
82
107
 public:
83
 
  ParserImpl(io::ZeroCopyInputStream* input_stream,
84
 
             io::ErrorCollector* error_collector)
 
108
 
 
109
  // Determines if repeated values for a non-repeated field are
 
110
  // permitted, e.g., the string "foo: 1 foo: 2" for a
 
111
  // required/optional field named "foo".
 
112
  enum SingularOverwritePolicy {
 
113
    ALLOW_SINGULAR_OVERWRITES = 0,   // the last value is retained
 
114
    FORBID_SINGULAR_OVERWRITES = 1,  // an error is issued
 
115
  };
 
116
 
 
117
  ParserImpl(const Descriptor* root_message_type,
 
118
             io::ZeroCopyInputStream* input_stream,
 
119
             io::ErrorCollector* error_collector,
 
120
             SingularOverwritePolicy singular_overwrite_policy)
85
121
    : error_collector_(error_collector),
86
122
      tokenizer_error_collector_(this),
87
123
      tokenizer_(input_stream, &tokenizer_error_collector_),
88
 
      root_message_type_(NULL) {
 
124
      root_message_type_(root_message_type),
 
125
      singular_overwrite_policy_(singular_overwrite_policy),
 
126
      had_errors_(false) {
89
127
    // For backwards-compatibility with proto1, we need to allow the 'f' suffix
90
128
    // for floats.
91
129
    tokenizer_.set_allow_f_after_float(true);
103
141
  // false if an error occurs (an error will also be logged to
104
142
  // GOOGLE_LOG(ERROR)).
105
143
  bool Parse(Message* output) {
106
 
    Message::Reflection* reflection = output->GetReflection();
107
 
    const Descriptor* descriptor = output->GetDescriptor();
108
 
    root_message_type_ = descriptor;
109
 
 
110
144
    // Consume fields until we cannot do so anymore.
111
145
    while(true) {
112
146
      if (LookingAtType(io::Tokenizer::TYPE_END)) {
113
 
        return true;
 
147
        return !had_errors_;
114
148
      }
115
149
 
116
 
      DO(ConsumeField(reflection, descriptor));
 
150
      DO(ConsumeField(output));
117
151
    }
118
152
  }
119
153
 
120
154
  void ReportError(int line, int col, const string& message) {
 
155
    had_errors_ = true;
121
156
    if (error_collector_ == NULL) {
122
157
      if (line >= 0) {
123
158
        GOOGLE_LOG(ERROR) << "Error parsing text-format "
148
183
  // This method checks to see that the end delimeter at the conclusion of
149
184
  // the consumption matches the starting delimeter passed in here.
150
185
  bool ConsumeMessage(Message* message, const string delimeter) {
151
 
    Message::Reflection* reflection = message->GetReflection();
152
 
    const Descriptor* descriptor = message->GetDescriptor();
153
 
 
154
186
    while (!LookingAt(">") &&  !LookingAt("}")) {
155
 
      DO(ConsumeField(reflection, descriptor));
 
187
      DO(ConsumeField(message));
156
188
    }
157
189
 
158
190
    // Confirm that we have a valid ending delimeter.
163
195
 
164
196
  // Consumes the current field (as returned by the tokenizer) on the
165
197
  // passed in message.
166
 
  bool ConsumeField(Message::Reflection* reflection,
167
 
                    const Descriptor* descriptor) {
 
198
  bool ConsumeField(Message* message) {
 
199
    const Reflection* reflection = message->GetReflection();
 
200
    const Descriptor* descriptor = message->GetDescriptor();
 
201
 
168
202
    string field_name;
169
203
 
170
204
    const FieldDescriptor* field = NULL;
217
251
      }
218
252
    }
219
253
 
 
254
    // Fail if the field is not repeated and it has already been specified.
 
255
    if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
 
256
        !field->is_repeated() && reflection->HasField(*message, field)) {
 
257
      ReportError("Non-repeated field \"" + field_name +
 
258
                  "\" is specified multiple times.");
 
259
      return false;
 
260
    }
 
261
 
220
262
    // Perform special handling for embedded message types.
221
263
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
222
264
      string delimeter;
232
274
      }
233
275
 
234
276
      if (field->is_repeated()) {
235
 
        DO(ConsumeMessage(reflection->AddMessage(field), delimeter));
 
277
        DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
236
278
      } else {
237
 
        DO(ConsumeMessage(reflection->MutableMessage(field), delimeter));
 
279
        DO(ConsumeMessage(reflection->MutableMessage(message, field),
 
280
                          delimeter));
238
281
      }
239
282
    } else {
240
283
      DO(Consume(":"));
241
 
      DO(ConsumeFieldValue(reflection, field));
 
284
      DO(ConsumeFieldValue(message, reflection, field));
242
285
    }
243
286
 
244
287
    return true;
245
288
  }
246
289
 
247
 
  bool ConsumeFieldValue(Message::Reflection* reflection,
 
290
  bool ConsumeFieldValue(Message* message,
 
291
                         const Reflection* reflection,
248
292
                         const FieldDescriptor* field) {
249
293
 
250
294
// Define an easy to use macro for setting fields. This macro checks
252
296
// methods or not (in which case we need to use the Set methods).
253
297
#define SET_FIELD(CPPTYPE, VALUE)                                  \
254
298
        if (field->is_repeated()) {                                \
255
 
          reflection->Add##CPPTYPE(field, VALUE);                  \
 
299
          reflection->Add##CPPTYPE(message, field, VALUE);         \
256
300
        } else {                                                   \
257
 
          reflection->Set##CPPTYPE(field, VALUE);                  \
 
301
          reflection->Set##CPPTYPE(message, field, VALUE);         \
258
302
        }                                                          \
259
303
 
260
304
    switch(field->cpp_type()) {
520
564
  // collect any base-level parse errors and feed them to the ParserImpl.
521
565
  class ParserErrorCollector : public io::ErrorCollector {
522
566
   public:
523
 
    explicit ParserErrorCollector(TextFormat::ParserImpl* parser) :
 
567
    explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
524
568
        parser_(parser) { }
525
569
 
526
570
    virtual ~ParserErrorCollector() { };
531
575
 
532
576
   private:
533
577
    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
534
 
    TextFormat::ParserImpl* parser_;
 
578
    TextFormat::Parser::ParserImpl* parser_;
535
579
  };
536
580
 
537
581
  io::ErrorCollector* error_collector_;
538
582
  ParserErrorCollector tokenizer_error_collector_;
539
583
  io::Tokenizer tokenizer_;
540
584
  const Descriptor* root_message_type_;
 
585
  SingularOverwritePolicy singular_overwrite_policy_;
 
586
  bool had_errors_;
541
587
};
542
588
 
543
589
#undef DO
666
712
bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
667
713
                               Message* output) {
668
714
  output->Clear();
669
 
  return Merge(input, output);
 
715
  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
 
716
                    ParserImpl::FORBID_SINGULAR_OVERWRITES);
 
717
  return MergeUsingImpl(input, output, &parser);
670
718
}
671
719
 
672
720
bool TextFormat::Parser::ParseFromString(const string& input,
677
725
 
678
726
bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
679
727
                               Message* output) {
680
 
  ParserImpl parser(input, error_collector_);
681
 
  if (!parser.Parse(output)) return false;
 
728
  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
 
729
                    ParserImpl::ALLOW_SINGULAR_OVERWRITES);
 
730
  return MergeUsingImpl(input, output, &parser);
 
731
}
 
732
 
 
733
bool TextFormat::Parser::MergeFromString(const string& input,
 
734
                                         Message* output) {
 
735
  io::ArrayInputStream input_stream(input.data(), input.size());
 
736
  return Merge(&input_stream, output);
 
737
}
 
738
 
 
739
bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
 
740
                                        Message* output,
 
741
                                        ParserImpl* parser_impl) {
 
742
  if (!parser_impl->Parse(output)) return false;
682
743
  if (!allow_partial_ && !output->IsInitialized()) {
683
744
    vector<string> missing_fields;
684
745
    output->FindInitializationErrors(&missing_fields);
685
 
    parser.ReportError(-1, 0, "Message missing required fields: " +
686
 
                              JoinStrings(missing_fields, ", "));
 
746
    parser_impl->ReportError(-1, 0, "Message missing required fields: " +
 
747
                                    JoinStrings(missing_fields, ", "));
687
748
    return false;
688
749
  }
689
750
  return true;
690
751
}
691
752
 
692
 
bool TextFormat::Parser::MergeFromString(const string& input,
693
 
                                         Message* output) {
694
 
  io::ArrayInputStream input_stream(input.data(), input.size());
695
 
  return Merge(&input_stream, output);
696
 
}
697
 
 
698
 
 
699
753
/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
700
754
                                    Message* output) {
701
755
  return Parser().Parse(input, output);
728
782
  return result;
729
783
}
730
784
 
 
785
/* static */ bool TextFormat::PrintUnknownFieldsToString(
 
786
    const UnknownFieldSet& unknown_fields,
 
787
    string* output) {
 
788
  GOOGLE_DCHECK(output) << "output specified is NULL";
 
789
 
 
790
  output->clear();
 
791
  io::StringOutputStream output_stream(output);
 
792
  return PrintUnknownFields(unknown_fields, &output_stream);
 
793
}
 
794
 
731
795
/* static */ bool TextFormat::Print(const Message& message,
732
796
                                    io::ZeroCopyOutputStream* output) {
733
797
  TextGenerator generator(output);
734
798
 
735
 
  Print(message.GetDescriptor(), message.GetReflection(), generator);
736
 
 
737
 
  // Output false if the generator failed internally.
738
 
  return !generator.failed();
739
 
}
740
 
 
741
 
/* static */ void TextFormat::Print(const Descriptor* descriptor,
742
 
                                    const Message::Reflection* message,
 
799
  Print(message, generator);
 
800
 
 
801
  // Output false if the generator failed internally.
 
802
  return !generator.failed();
 
803
}
 
804
 
 
805
/* static */ bool TextFormat::PrintUnknownFields(
 
806
    const UnknownFieldSet& unknown_fields,
 
807
    io::ZeroCopyOutputStream* output) {
 
808
  TextGenerator generator(output);
 
809
 
 
810
  PrintUnknownFields(unknown_fields, generator);
 
811
 
 
812
  // Output false if the generator failed internally.
 
813
  return !generator.failed();
 
814
}
 
815
 
 
816
/* static */ void TextFormat::Print(const Message& message,
743
817
                                    TextGenerator& generator) {
 
818
  const Reflection* reflection = message.GetReflection();
744
819
  vector<const FieldDescriptor*> fields;
745
 
  message->ListFields(&fields);
 
820
  reflection->ListFields(message, &fields);
746
821
  for (int i = 0; i < fields.size(); i++) {
747
 
    PrintField(fields[i], message, generator);
 
822
    PrintField(message, reflection, fields[i], generator);
748
823
  }
749
 
  PrintUnknownFields(message->GetUnknownFields(), generator);
 
824
  PrintUnknownFields(reflection->GetUnknownFields(message), generator);
750
825
}
751
826
 
752
827
/* static */ void TextFormat::PrintFieldValueToString(
761
836
  io::StringOutputStream output_stream(output);
762
837
  TextGenerator generator(&output_stream);
763
838
 
764
 
  PrintFieldValue(message.GetReflection(), field, index, generator);
 
839
  PrintFieldValue(message, message.GetReflection(), field, index, generator);
765
840
}
766
841
 
767
 
/* static */ void TextFormat::PrintField(const FieldDescriptor* field,
768
 
                                         const Message::Reflection* message,
 
842
/* static */ void TextFormat::PrintField(const Message& message,
 
843
                                         const Reflection* reflection,
 
844
                                         const FieldDescriptor* field,
769
845
                                         TextGenerator& generator) {
770
846
  int count = 0;
771
847
 
772
848
  if (field->is_repeated()) {
773
 
    count = message->FieldSize(field);
774
 
  } else if (message->HasField(field)) {
 
849
    count = reflection->FieldSize(message, field);
 
850
  } else if (reflection->HasField(message, field)) {
775
851
    count = 1;
776
852
  }
777
853
 
810
886
      field_index = -1;
811
887
    }
812
888
 
813
 
    PrintFieldValue(message, field, field_index, generator);
 
889
    PrintFieldValue(message, reflection, field, field_index, generator);
814
890
 
815
891
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
816
892
        generator.Outdent();
822
898
}
823
899
 
824
900
/* static */ void TextFormat::PrintFieldValue(
825
 
    const Message::Reflection* reflection,
 
901
    const Message& message,
 
902
    const Reflection* reflection,
826
903
    const FieldDescriptor* field,
827
904
    int index,
828
905
    TextGenerator& generator) {
833
910
#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING)                             \
834
911
      case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
835
912
        generator.Print(TO_STRING(field->is_repeated() ?                     \
836
 
                         reflection->GetRepeated##METHOD(field, index) :     \
837
 
                         reflection->Get##METHOD(field)));                   \
 
913
          reflection->GetRepeated##METHOD(message, field, index) :           \
 
914
          reflection->Get##METHOD(message, field)));                         \
838
915
        break;                                                               \
839
916
 
840
917
      OUTPUT_FIELD( INT32,  Int32, SimpleItoa);
848
925
      case FieldDescriptor::CPPTYPE_STRING: {
849
926
        string scratch;
850
927
        const string& value = field->is_repeated() ?
851
 
            reflection->GetRepeatedStringReference(field, index, &scratch) :
852
 
            reflection->GetStringReference(field, &scratch);
 
928
            reflection->GetRepeatedStringReference(
 
929
              message, field, index, &scratch) :
 
930
            reflection->GetStringReference(message, field, &scratch);
853
931
 
854
932
        generator.Print("\"");
855
933
        generator.Print(CEscape(value));
860
938
 
861
939
      case FieldDescriptor::CPPTYPE_BOOL:
862
940
        if (field->is_repeated()) {
863
 
          generator.Print(reflection->GetRepeatedBool(field, index)
 
941
          generator.Print(reflection->GetRepeatedBool(message, field, index)
864
942
                          ? "true" : "false");
865
943
        } else {
866
 
          generator.Print(reflection->GetBool(field) ? "true" : "false");
 
944
          generator.Print(reflection->GetBool(message, field)
 
945
                          ? "true" : "false");
867
946
        }
868
947
        break;
869
948
 
870
949
      case FieldDescriptor::CPPTYPE_ENUM:
871
950
        generator.Print(field->is_repeated() ?
872
 
                        reflection->GetRepeatedEnum(field, index)->name()
873
 
                        : reflection->GetEnum(field)->name());
 
951
          reflection->GetRepeatedEnum(message, field, index)->name() :
 
952
          reflection->GetEnum(message, field)->name());
874
953
        break;
875
954
 
876
955
      case FieldDescriptor::CPPTYPE_MESSAGE:
877
 
        Print(field->message_type(),
878
 
              field->is_repeated() ?
879
 
              reflection->GetRepeatedMessage(field, index).GetReflection()
880
 
              : reflection->GetMessage(field).GetReflection(), generator);
 
956
        Print(field->is_repeated() ?
 
957
                reflection->GetRepeatedMessage(message, field, index) :
 
958
                reflection->GetMessage(message, field),
 
959
              generator);
881
960
        break;
882
961
  }
883
962
}
922
1001
    }
923
1002
    for (int j = 0; j < field.length_delimited_size(); j++) {
924
1003
      generator.Print(field_number);
925
 
      generator.Print(": \"");
926
 
      generator.Print(CEscape(field.length_delimited(j)));
927
 
      generator.Print("\"\n");
 
1004
      const string& value = field.length_delimited(j);
 
1005
      UnknownFieldSet embedded_unknown_fields;
 
1006
      if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
 
1007
        // This field is parseable as a Message.
 
1008
        // So it is probably an embedded message.
 
1009
        generator.Print(" {\n");
 
1010
        generator.Indent();
 
1011
        PrintUnknownFields(embedded_unknown_fields, generator);
 
1012
        generator.Outdent();
 
1013
        generator.Print("}\n");
 
1014
      } else {
 
1015
        // This field is not parseable as a Message.
 
1016
        // So it is probably just a plain string.
 
1017
        generator.Print(": \"");
 
1018
        generator.Print(CEscape(value));
 
1019
        generator.Print("\"\n");
 
1020
      }
928
1021
    }
929
1022
    for (int j = 0; j < field.group_size(); j++) {
930
1023
      generator.Print(field_number);