JsonFormat.java
Go to the documentation of this file.
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 package com.google.protobuf.util;
32 
33 import com.google.common.base.Preconditions;
34 import com.google.common.io.BaseEncoding;
35 import com.google.errorprone.annotations.CanIgnoreReturnValue;
36 import com.google.gson.Gson;
37 import com.google.gson.GsonBuilder;
38 import com.google.gson.JsonArray;
39 import com.google.gson.JsonElement;
40 import com.google.gson.JsonIOException;
41 import com.google.gson.JsonNull;
42 import com.google.gson.JsonObject;
43 import com.google.gson.JsonParser;
44 import com.google.gson.JsonPrimitive;
45 import com.google.gson.stream.JsonReader;
46 import com.google.protobuf.Any;
60 import com.google.protobuf.FieldMask;
61 import com.google.protobuf.FloatValue;
63 import com.google.protobuf.Int64Value;
66 import com.google.protobuf.Message;
68 import com.google.protobuf.NullValue;
70 import com.google.protobuf.Struct;
71 import com.google.protobuf.Timestamp;
74 import com.google.protobuf.Value;
75 import java.io.IOException;
76 import java.io.Reader;
77 import java.io.StringReader;
78 import java.math.BigDecimal;
79 import java.math.BigInteger;
80 import java.text.ParseException;
81 import java.util.Collection;
82 import java.util.Collections;
83 import java.util.Comparator;
84 import java.util.HashMap;
85 import java.util.HashSet;
86 import java.util.List;
87 import java.util.Map;
88 import java.util.Set;
89 import java.util.TreeMap;
90 import java.util.logging.Logger;
91 
101 public class JsonFormat {
102  private static final Logger logger = Logger.getLogger(JsonFormat.class.getName());
103 
104  private JsonFormat() {}
105 
109  public static Printer printer() {
110  return new Printer(
111  TypeRegistry.getEmptyTypeRegistry(), false, Collections.<FieldDescriptor>emptySet(),
112  false, false, false, false);
113  }
114 
118  public static class Printer {
119  private final TypeRegistry registry;
120  // NOTE: There are 3 states for these *defaultValueFields variables:
121  // 1) Default - alwaysOutput is false & including is empty set. Fields only output if they are
122  // set to non-default values.
123  // 2) No-args includingDefaultValueFields() called - alwaysOutput is true & including is
124  // irrelevant (but set to empty set). All fields are output regardless of their values.
125  // 3) includingDefaultValueFields(Set<FieldDescriptor>) called - alwaysOutput is false &
126  // including is set to the specified set. Fields in that set are always output & fields not
127  // in that set are only output if set to non-default values.
129  private Set<FieldDescriptor> includingDefaultValueFields;
130  private final boolean preservingProtoFieldNames;
131  private final boolean omittingInsignificantWhitespace;
132  private final boolean printingEnumsAsInts;
133  private final boolean sortingMapKeys;
134 
135  private Printer(
138  Set<FieldDescriptor> includingDefaultValueFields,
141  boolean printingEnumsAsInts,
142  boolean sortingMapKeys) {
143  this.registry = registry;
144  this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
145  this.includingDefaultValueFields = includingDefaultValueFields;
146  this.preservingProtoFieldNames = preservingProtoFieldNames;
147  this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
148  this.printingEnumsAsInts = printingEnumsAsInts;
149  this.sortingMapKeys = sortingMapKeys;
150  }
151 
159  if (this.registry != TypeRegistry.getEmptyTypeRegistry()) {
160  throw new IllegalArgumentException("Only one registry is allowed.");
161  }
162  return new Printer(
163  registry,
170  }
171 
180  return new Printer(
181  registry,
182  true,
183  Collections.<FieldDescriptor>emptySet(),
188  }
189 
198  return new Printer(
199  registry,
201  Collections.<FieldDescriptor>emptySet(),
204  true,
206  }
207 
209  if (printingEnumsAsInts) {
210  throw new IllegalStateException("JsonFormat printingEnumsAsInts has already been set.");
211  }
212  }
213 
221  public Printer includingDefaultValueFields(Set<FieldDescriptor> fieldsToAlwaysOutput) {
222  Preconditions.checkArgument(
223  null != fieldsToAlwaysOutput && !fieldsToAlwaysOutput.isEmpty(),
224  "Non-empty Set must be supplied for includingDefaultValueFields.");
225 
227  return new Printer(
228  registry,
229  false,
230  Collections.unmodifiableSet(new HashSet<>(fieldsToAlwaysOutput)),
235  }
236 
239  throw new IllegalStateException(
240  "JsonFormat includingDefaultValueFields has already been set.");
241  }
242  }
243 
251  return new Printer(
252  registry,
255  true,
259  }
260 
261 
280  return new Printer(
281  registry,
285  true,
288  }
289 
303  return new Printer(
304  registry,
310  true);
311  }
312 
320  public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
321  // TODO(xiaofeng): Investigate the allocation overhead and optimize for
322  // mobile.
323  new PrinterImpl(
324  registry,
328  output,
332  .print(message);
333  }
334 
340  try {
341  StringBuilder builder = new StringBuilder();
342  appendTo(message, builder);
343  return builder.toString();
344  } catch (InvalidProtocolBufferException e) {
345  throw e;
346  } catch (IOException e) {
347  // Unexpected IOException.
348  throw new IllegalStateException(e);
349  }
350  }
351  }
352 
356  public static Parser parser() {
358  }
359 
363  public static class Parser {
364  private final TypeRegistry registry;
365  private final boolean ignoringUnknownFields;
366  private final int recursionLimit;
367 
368  // The default parsing recursion limit is aligned with the proto binary parser.
369  private static final int DEFAULT_RECURSION_LIMIT = 100;
370 
371  private Parser(TypeRegistry registry, boolean ignoreUnknownFields, int recursionLimit) {
372  this.registry = registry;
373  this.ignoringUnknownFields = ignoreUnknownFields;
374  this.recursionLimit = recursionLimit;
375  }
376 
384  if (this.registry != TypeRegistry.getEmptyTypeRegistry()) {
385  throw new IllegalArgumentException("Only one registry is allowed.");
386  }
388  }
389 
395  return new Parser(this.registry, true, recursionLimit);
396  }
397 
404  public void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException {
405  // TODO(xiaofeng): Investigate the allocation overhead and optimize for
406  // mobile.
407  new ParserImpl(registry, ignoringUnknownFields, recursionLimit).merge(json, builder);
408  }
409 
417  public void merge(Reader json, Message.Builder builder) throws IOException {
418  // TODO(xiaofeng): Investigate the allocation overhead and optimize for
419  // mobile.
420  new ParserImpl(registry, ignoringUnknownFields, recursionLimit).merge(json, builder);
421  }
422 
423  // For testing only.
424  Parser usingRecursionLimit(int recursionLimit) {
426  }
427  }
428 
436  public static class TypeRegistry {
437  private static class EmptyTypeRegistryHolder {
438  private static final TypeRegistry EMPTY =
439  new TypeRegistry(Collections.<String, Descriptor>emptyMap());
440  }
441 
444  }
445 
446  public static Builder newBuilder() {
447  return new Builder();
448  }
449 
454  public Descriptor find(String name) {
455  return types.get(name);
456  }
457 
458  /* @Nullable */
459  Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException {
460  return find(getTypeName(typeUrl));
461  }
462 
463  private final Map<String, Descriptor> types;
464 
465  private TypeRegistry(Map<String, Descriptor> types) {
466  this.types = types;
467  }
468 
469 
471  public static class Builder {
472  private Builder() {}
473 
478  @CanIgnoreReturnValue
479  public Builder add(Descriptor messageType) {
480  if (types == null) {
481  throw new IllegalStateException("A TypeRegistry.Builer can only be used once.");
482  }
483  addFile(messageType.getFile());
484  return this;
485  }
486 
491  @CanIgnoreReturnValue
492  public Builder add(Iterable<Descriptor> messageTypes) {
493  if (types == null) {
494  throw new IllegalStateException("A TypeRegistry.Builder can only be used once.");
495  }
496  for (Descriptor type : messageTypes) {
497  addFile(type.getFile());
498  }
499  return this;
500  }
501 
506  public TypeRegistry build() {
507  TypeRegistry result = new TypeRegistry(types);
508  // Make sure the built {@link TypeRegistry} is immutable.
509  types = null;
510  return result;
511  }
512 
513  private void addFile(FileDescriptor file) {
514  // Skip the file if it's already added.
515  if (!files.add(file.getFullName())) {
516  return;
517  }
518  for (FileDescriptor dependency : file.getDependencies()) {
519  addFile(dependency);
520  }
521  for (Descriptor message : file.getMessageTypes()) {
523  }
524  }
525 
526  private void addMessage(Descriptor message) {
527  for (Descriptor nestedType : message.getNestedTypes()) {
528  addMessage(nestedType);
529  }
530 
531  if (types.containsKey(message.getFullName())) {
532  logger.warning("Type " + message.getFullName() + " is added multiple times.");
533  return;
534  }
535 
536  types.put(message.getFullName(), message);
537  }
538 
539  private final Set<String> files = new HashSet<String>();
540  private Map<String, Descriptor> types = new HashMap<String, Descriptor>();
541  }
542  }
543 
548  interface TextGenerator {
549  void indent();
550 
551  void outdent();
552 
553  void print(final CharSequence text) throws IOException;
554  }
555 
559  private static final class CompactTextGenerator implements TextGenerator {
560  private final Appendable output;
561 
562  private CompactTextGenerator(final Appendable output) {
563  this.output = output;
564  }
565 
567  @Override
568  public void indent() {}
569 
571  @Override
572  public void outdent() {}
573 
575  @Override
576  public void print(final CharSequence text) throws IOException {
577  output.append(text);
578  }
579  }
583  private static final class PrettyTextGenerator implements TextGenerator {
584  private final Appendable output;
585  private final StringBuilder indent = new StringBuilder();
586  private boolean atStartOfLine = true;
587 
588  private PrettyTextGenerator(final Appendable output) {
589  this.output = output;
590  }
591 
597  @Override
598  public void indent() {
599  indent.append(" ");
600  }
601 
603  @Override
604  public void outdent() {
605  final int length = indent.length();
606  if (length < 2) {
607  throw new IllegalArgumentException(" Outdent() without matching Indent().");
608  }
609  indent.delete(length - 2, length);
610  }
611 
613  @Override
614  public void print(final CharSequence text) throws IOException {
615  final int size = text.length();
616  int pos = 0;
617 
618  for (int i = 0; i < size; i++) {
619  if (text.charAt(i) == '\n') {
620  write(text.subSequence(pos, i + 1));
621  pos = i + 1;
622  atStartOfLine = true;
623  }
624  }
625  write(text.subSequence(pos, size));
626  }
627 
628  private void write(final CharSequence data) throws IOException {
629  if (data.length() == 0) {
630  return;
631  }
632  if (atStartOfLine) {
633  atStartOfLine = false;
634  output.append(indent);
635  }
636  output.append(data);
637  }
638  }
639 
643  private static final class PrinterImpl {
644  private final TypeRegistry registry;
645  private final boolean alwaysOutputDefaultValueFields;
646  private final Set<FieldDescriptor> includingDefaultValueFields;
647  private final boolean preservingProtoFieldNames;
648  private final boolean printingEnumsAsInts;
649  private final boolean sortingMapKeys;
650  private final TextGenerator generator;
651  // We use Gson to help handle string escapes.
652  private final Gson gson;
653  private final CharSequence blankOrSpace;
654  private final CharSequence blankOrNewLine;
655 
656  private static class GsonHolder {
657  private static final Gson DEFAULT_GSON = new GsonBuilder().create();
658  }
659 
660  PrinterImpl(
663  Set<FieldDescriptor> includingDefaultValueFields,
665  Appendable jsonOutput,
666  boolean omittingInsignificantWhitespace,
667  boolean printingEnumsAsInts,
668  boolean sortingMapKeys) {
669  this.registry = registry;
670  this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
671  this.includingDefaultValueFields = includingDefaultValueFields;
672  this.preservingProtoFieldNames = preservingProtoFieldNames;
673  this.printingEnumsAsInts = printingEnumsAsInts;
674  this.sortingMapKeys = sortingMapKeys;
675  this.gson = GsonHolder.DEFAULT_GSON;
676  // json format related properties, determined by printerType
677  if (omittingInsignificantWhitespace) {
678  this.generator = new CompactTextGenerator(jsonOutput);
679  this.blankOrSpace = "";
680  this.blankOrNewLine = "";
681  } else {
682  this.generator = new PrettyTextGenerator(jsonOutput);
683  this.blankOrSpace = " ";
684  this.blankOrNewLine = "\n";
685  }
686  }
687 
688  void print(MessageOrBuilder message) throws IOException {
689  WellKnownTypePrinter specialPrinter =
690  wellKnownTypePrinters.get(message.getDescriptorForType().getFullName());
691  if (specialPrinter != null) {
692  specialPrinter.print(this, message);
693  return;
694  }
695  print(message, null);
696  }
697 
698  private interface WellKnownTypePrinter {
699  void print(PrinterImpl printer, MessageOrBuilder message) throws IOException;
700  }
701 
702  private static final Map<String, WellKnownTypePrinter> wellKnownTypePrinters =
704 
705  private static Map<String, WellKnownTypePrinter> buildWellKnownTypePrinters() {
706  Map<String, WellKnownTypePrinter> printers = new HashMap<String, WellKnownTypePrinter>();
707  // Special-case Any.
708  printers.put(
709  Any.getDescriptor().getFullName(),
710  new WellKnownTypePrinter() {
711  @Override
712  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
713  printer.printAny(message);
714  }
715  });
716  // Special-case wrapper types.
717  WellKnownTypePrinter wrappersPrinter =
718  new WellKnownTypePrinter() {
719  @Override
720  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
721  printer.printWrapper(message);
722  }
723  };
724  printers.put(BoolValue.getDescriptor().getFullName(), wrappersPrinter);
725  printers.put(Int32Value.getDescriptor().getFullName(), wrappersPrinter);
726  printers.put(UInt32Value.getDescriptor().getFullName(), wrappersPrinter);
727  printers.put(Int64Value.getDescriptor().getFullName(), wrappersPrinter);
728  printers.put(UInt64Value.getDescriptor().getFullName(), wrappersPrinter);
729  printers.put(StringValue.getDescriptor().getFullName(), wrappersPrinter);
730  printers.put(BytesValue.getDescriptor().getFullName(), wrappersPrinter);
731  printers.put(FloatValue.getDescriptor().getFullName(), wrappersPrinter);
732  printers.put(DoubleValue.getDescriptor().getFullName(), wrappersPrinter);
733  // Special-case Timestamp.
734  printers.put(
735  Timestamp.getDescriptor().getFullName(),
736  new WellKnownTypePrinter() {
737  @Override
738  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
739  printer.printTimestamp(message);
740  }
741  });
742  // Special-case Duration.
743  printers.put(
744  Duration.getDescriptor().getFullName(),
745  new WellKnownTypePrinter() {
746  @Override
747  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
748  printer.printDuration(message);
749  }
750  });
751  // Special-case FieldMask.
752  printers.put(
753  FieldMask.getDescriptor().getFullName(),
754  new WellKnownTypePrinter() {
755  @Override
756  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
757  printer.printFieldMask(message);
758  }
759  });
760  // Special-case Struct.
761  printers.put(
762  Struct.getDescriptor().getFullName(),
763  new WellKnownTypePrinter() {
764  @Override
765  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
766  printer.printStruct(message);
767  }
768  });
769  // Special-case Value.
770  printers.put(
771  Value.getDescriptor().getFullName(),
772  new WellKnownTypePrinter() {
773  @Override
774  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
775  printer.printValue(message);
776  }
777  });
778  // Special-case ListValue.
779  printers.put(
780  ListValue.getDescriptor().getFullName(),
781  new WellKnownTypePrinter() {
782  @Override
783  public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
784  printer.printListValue(message);
785  }
786  });
787  return printers;
788  }
789 
791  private void printAny(MessageOrBuilder message) throws IOException {
792  if (Any.getDefaultInstance().equals(message)) {
793  generator.print("{}");
794  return;
795  }
796  Descriptor descriptor = message.getDescriptorForType();
797  FieldDescriptor typeUrlField = descriptor.findFieldByName("type_url");
798  FieldDescriptor valueField = descriptor.findFieldByName("value");
799  // Validates type of the message. Note that we can't just cast the message
800  // to com.google.protobuf.Any because it might be a DynamicMessage.
801  if (typeUrlField == null
802  || valueField == null
803  || typeUrlField.getType() != FieldDescriptor.Type.STRING
804  || valueField.getType() != FieldDescriptor.Type.BYTES) {
805  throw new InvalidProtocolBufferException("Invalid Any type.");
806  }
807  String typeUrl = (String) message.getField(typeUrlField);
808  Descriptor type = registry.getDescriptorForTypeUrl(typeUrl);
809  if (type == null) {
810  throw new InvalidProtocolBufferException("Cannot find type for url: " + typeUrl);
811  }
812  ByteString content = (ByteString) message.getField(valueField);
813  Message contentMessage =
816  if (printer != null) {
817  // If the type is one of the well-known types, we use a special
818  // formatting.
819  generator.print("{" + blankOrNewLine);
820  generator.indent();
821  generator.print("\"@type\":" + blankOrSpace + gson.toJson(typeUrl) + "," + blankOrNewLine);
822  generator.print("\"value\":" + blankOrSpace);
823  printer.print(this, contentMessage);
824  generator.print(blankOrNewLine);
825  generator.outdent();
826  generator.print("}");
827  } else {
828  // Print the content message instead (with a "@type" field added).
829  print(contentMessage, typeUrl);
830  }
831  }
832 
834  private void printWrapper(MessageOrBuilder message) throws IOException {
835  Descriptor descriptor = message.getDescriptorForType();
836  FieldDescriptor valueField = descriptor.findFieldByName("value");
837  if (valueField == null) {
838  throw new InvalidProtocolBufferException("Invalid Wrapper type.");
839  }
840  // When formatting wrapper types, we just print its value field instead of
841  // the whole message.
842  printSingleFieldValue(valueField, message.getField(valueField));
843  }
844 
846  if (message instanceof Message) {
847  return ((Message) message).toByteString();
848  } else {
849  return ((Message.Builder) message).build().toByteString();
850  }
851  }
852 
854  private void printTimestamp(MessageOrBuilder message) throws IOException {
856  generator.print("\"" + Timestamps.toString(value) + "\"");
857  }
858 
860  private void printDuration(MessageOrBuilder message) throws IOException {
862  generator.print("\"" + Durations.toString(value) + "\"");
863  }
864 
866  private void printFieldMask(MessageOrBuilder message) throws IOException {
868  generator.print("\"" + FieldMaskUtil.toJsonString(value) + "\"");
869  }
870 
872  private void printStruct(MessageOrBuilder message) throws IOException {
873  Descriptor descriptor = message.getDescriptorForType();
874  FieldDescriptor field = descriptor.findFieldByName("fields");
875  if (field == null) {
876  throw new InvalidProtocolBufferException("Invalid Struct type.");
877  }
878  // Struct is formatted as a map object.
880  }
881 
883  private void printValue(MessageOrBuilder message) throws IOException {
884  // For a Value message, only the value of the field is formatted.
885  Map<FieldDescriptor, Object> fields = message.getAllFields();
886  if (fields.isEmpty()) {
887  // No value set.
888  generator.print("null");
889  return;
890  }
891  // A Value message can only have at most one field set (it only contains
892  // an oneof).
893  if (fields.size() != 1) {
894  throw new InvalidProtocolBufferException("Invalid Value type.");
895  }
896  for (Map.Entry<FieldDescriptor, Object> entry : fields.entrySet()) {
897  printSingleFieldValue(entry.getKey(), entry.getValue());
898  }
899  }
900 
902  private void printListValue(MessageOrBuilder message) throws IOException {
903  Descriptor descriptor = message.getDescriptorForType();
904  FieldDescriptor field = descriptor.findFieldByName("values");
905  if (field == null) {
906  throw new InvalidProtocolBufferException("Invalid ListValue type.");
907  }
909  }
910 
912  private void print(MessageOrBuilder message, String typeUrl) throws IOException {
913  generator.print("{" + blankOrNewLine);
914  generator.indent();
915 
916  boolean printedField = false;
917  if (typeUrl != null) {
918  generator.print("\"@type\":" + blankOrSpace + gson.toJson(typeUrl));
919  printedField = true;
920  }
921  Map<FieldDescriptor, Object> fieldsToPrint = null;
923  fieldsToPrint = new TreeMap<FieldDescriptor, Object>(message.getAllFields());
924  for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
925  if (field.isOptional()) {
926  if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
927  && !message.hasField(field)) {
928  // Always skip empty optional message fields. If not we will recurse indefinitely if
929  // a message has itself as a sub-field.
930  continue;
931  }
932  OneofDescriptor oneof = field.getContainingOneof();
933  if (oneof != null && !message.hasField(field)) {
934  // Skip all oneof fields except the one that is actually set
935  continue;
936  }
937  }
938  if (!fieldsToPrint.containsKey(field)
940  fieldsToPrint.put(field, message.getField(field));
941  }
942  }
943  } else {
944  fieldsToPrint = message.getAllFields();
945  }
946  for (Map.Entry<FieldDescriptor, Object> field : fieldsToPrint.entrySet()) {
947  if (printedField) {
948  // Add line-endings for the previous field.
949  generator.print("," + blankOrNewLine);
950  } else {
951  printedField = true;
952  }
953  printField(field.getKey(), field.getValue());
954  }
955 
956  // Add line-endings for the last field.
957  if (printedField) {
958  generator.print(blankOrNewLine);
959  }
960  generator.outdent();
961  generator.print("}");
962  }
963 
964  private void printField(FieldDescriptor field, Object value) throws IOException {
966  generator.print("\"" + field.getName() + "\":" + blankOrSpace);
967  } else {
968  generator.print("\"" + field.getJsonName() + "\":" + blankOrSpace);
969  }
970  if (field.isMapField()) {
972  } else if (field.isRepeated()) {
974  } else {
976  }
977  }
978 
979  @SuppressWarnings("rawtypes")
980  private void printRepeatedFieldValue(FieldDescriptor field, Object value) throws IOException {
981  generator.print("[");
982  boolean printedElement = false;
983  for (Object element : (List) value) {
984  if (printedElement) {
985  generator.print("," + blankOrSpace);
986  } else {
987  printedElement = true;
988  }
989  printSingleFieldValue(field, element);
990  }
991  generator.print("]");
992  }
993 
994  @SuppressWarnings("rawtypes")
995  private void printMapFieldValue(FieldDescriptor field, Object value) throws IOException {
996  Descriptor type = field.getMessageType();
997  FieldDescriptor keyField = type.findFieldByName("key");
998  FieldDescriptor valueField = type.findFieldByName("value");
999  if (keyField == null || valueField == null) {
1000  throw new InvalidProtocolBufferException("Invalid map field.");
1001  }
1002  generator.print("{" + blankOrNewLine);
1003  generator.indent();
1004 
1005  @SuppressWarnings("unchecked") // Object guaranteed to be a List for a map field.
1006  Collection<Object> elements = (List<Object>) value;
1007  if (sortingMapKeys && !elements.isEmpty()) {
1008  Comparator<Object> cmp = null;
1009  if (keyField.getType() == FieldDescriptor.Type.STRING) {
1010  cmp = new Comparator<Object>() {
1011  @Override
1012  public int compare(final Object o1, final Object o2) {
1013  ByteString s1 = ByteString.copyFromUtf8((String) o1);
1014  ByteString s2 = ByteString.copyFromUtf8((String) o2);
1015  return ByteString.unsignedLexicographicalComparator().compare(s1, s2);
1016  }
1017  };
1018  }
1019  TreeMap<Object, Object> tm = new TreeMap<Object, Object>(cmp);
1020  for (Object element : elements) {
1021  Message entry = (Message) element;
1022  Object entryKey = entry.getField(keyField);
1023  tm.put(entryKey, element);
1024  }
1025  elements = tm.values();
1026  }
1027 
1028  boolean printedElement = false;
1029  for (Object element : elements) {
1030  Message entry = (Message) element;
1031  Object entryKey = entry.getField(keyField);
1032  Object entryValue = entry.getField(valueField);
1033  if (printedElement) {
1034  generator.print("," + blankOrNewLine);
1035  } else {
1036  printedElement = true;
1037  }
1038  // Key fields are always double-quoted.
1039  printSingleFieldValue(keyField, entryKey, true);
1040  generator.print(":" + blankOrSpace);
1041  printSingleFieldValue(valueField, entryValue);
1042  }
1043  if (printedElement) {
1044  generator.print(blankOrNewLine);
1045  }
1046  generator.outdent();
1047  generator.print("}");
1048  }
1049 
1050  private void printSingleFieldValue(FieldDescriptor field, Object value) throws IOException {
1052  }
1053 
1061  final FieldDescriptor field, final Object value, boolean alwaysWithQuotes)
1062  throws IOException {
1063  switch (field.getType()) {
1064  case INT32:
1065  case SINT32:
1066  case SFIXED32:
1067  if (alwaysWithQuotes) {
1068  generator.print("\"");
1069  }
1070  generator.print(((Integer) value).toString());
1071  if (alwaysWithQuotes) {
1072  generator.print("\"");
1073  }
1074  break;
1075 
1076  case INT64:
1077  case SINT64:
1078  case SFIXED64:
1079  generator.print("\"" + ((Long) value).toString() + "\"");
1080  break;
1081 
1082  case BOOL:
1083  if (alwaysWithQuotes) {
1084  generator.print("\"");
1085  }
1086  if (((Boolean) value).booleanValue()) {
1087  generator.print("true");
1088  } else {
1089  generator.print("false");
1090  }
1091  if (alwaysWithQuotes) {
1092  generator.print("\"");
1093  }
1094  break;
1095 
1096  case FLOAT:
1097  Float floatValue = (Float) value;
1098  if (floatValue.isNaN()) {
1099  generator.print("\"NaN\"");
1100  } else if (floatValue.isInfinite()) {
1101  if (floatValue < 0) {
1102  generator.print("\"-Infinity\"");
1103  } else {
1104  generator.print("\"Infinity\"");
1105  }
1106  } else {
1107  if (alwaysWithQuotes) {
1108  generator.print("\"");
1109  }
1110  generator.print(floatValue.toString());
1111  if (alwaysWithQuotes) {
1112  generator.print("\"");
1113  }
1114  }
1115  break;
1116 
1117  case DOUBLE:
1118  Double doubleValue = (Double) value;
1119  if (doubleValue.isNaN()) {
1120  generator.print("\"NaN\"");
1121  } else if (doubleValue.isInfinite()) {
1122  if (doubleValue < 0) {
1123  generator.print("\"-Infinity\"");
1124  } else {
1125  generator.print("\"Infinity\"");
1126  }
1127  } else {
1128  if (alwaysWithQuotes) {
1129  generator.print("\"");
1130  }
1131  generator.print(doubleValue.toString());
1132  if (alwaysWithQuotes) {
1133  generator.print("\"");
1134  }
1135  }
1136  break;
1137 
1138  case UINT32:
1139  case FIXED32:
1140  if (alwaysWithQuotes) {
1141  generator.print("\"");
1142  }
1143  generator.print(unsignedToString((Integer) value));
1144  if (alwaysWithQuotes) {
1145  generator.print("\"");
1146  }
1147  break;
1148 
1149  case UINT64:
1150  case FIXED64:
1151  generator.print("\"" + unsignedToString((Long) value) + "\"");
1152  break;
1153 
1154  case STRING:
1155  generator.print(gson.toJson(value));
1156  break;
1157 
1158  case BYTES:
1159  generator.print("\"");
1160  generator.print(BaseEncoding.base64().encode(((ByteString) value).toByteArray()));
1161  generator.print("\"");
1162  break;
1163 
1164  case ENUM:
1165  // Special-case google.protobuf.NullValue (it's an Enum).
1166  if (field.getEnumType().getFullName().equals("google.protobuf.NullValue")) {
1167  // No matter what value it contains, we always print it as "null".
1168  if (alwaysWithQuotes) {
1169  generator.print("\"");
1170  }
1171  generator.print("null");
1172  if (alwaysWithQuotes) {
1173  generator.print("\"");
1174  }
1175  } else {
1176  if (printingEnumsAsInts || ((EnumValueDescriptor) value).getIndex() == -1) {
1177  generator.print(String.valueOf(((EnumValueDescriptor) value).getNumber()));
1178  } else {
1179  generator.print("\"" + ((EnumValueDescriptor) value).getName() + "\"");
1180  }
1181  }
1182  break;
1183 
1184  case MESSAGE:
1185  case GROUP:
1186  print((Message) value);
1187  break;
1188  }
1189  }
1190  }
1191 
1193  private static String unsignedToString(final int value) {
1194  if (value >= 0) {
1195  return Integer.toString(value);
1196  } else {
1197  return Long.toString(value & 0x00000000FFFFFFFFL);
1198  }
1199  }
1200 
1202  private static String unsignedToString(final long value) {
1203  if (value >= 0) {
1204  return Long.toString(value);
1205  } else {
1206  // Pull off the most-significant bit so that BigInteger doesn't think
1207  // the number is negative, then set it again using setBit().
1208  return BigInteger.valueOf(value & Long.MAX_VALUE).setBit(Long.SIZE - 1).toString();
1209  }
1210  }
1211 
1212  private static String getTypeName(String typeUrl) throws InvalidProtocolBufferException {
1213  String[] parts = typeUrl.split("/");
1214  if (parts.length == 1) {
1215  throw new InvalidProtocolBufferException("Invalid type url found: " + typeUrl);
1216  }
1217  return parts[parts.length - 1];
1218  }
1219 
1220  private static class ParserImpl {
1221  private final TypeRegistry registry;
1222  private final JsonParser jsonParser;
1223  private final boolean ignoringUnknownFields;
1224  private final int recursionLimit;
1225  private int currentDepth;
1226 
1227  ParserImpl(TypeRegistry registry, boolean ignoreUnknownFields, int recursionLimit) {
1228  this.registry = registry;
1229  this.ignoringUnknownFields = ignoreUnknownFields;
1230  this.jsonParser = new JsonParser();
1231  this.recursionLimit = recursionLimit;
1232  this.currentDepth = 0;
1233  }
1234 
1235  void merge(Reader json, Message.Builder builder) throws IOException {
1236  try {
1237  JsonReader reader = new JsonReader(json);
1238  reader.setLenient(false);
1239  merge(jsonParser.parse(reader), builder);
1240  } catch (InvalidProtocolBufferException e) {
1241  throw e;
1242  } catch (JsonIOException e) {
1243  // Unwrap IOException.
1244  if (e.getCause() instanceof IOException) {
1245  throw (IOException) e.getCause();
1246  } else {
1247  throw new InvalidProtocolBufferException(e.getMessage());
1248  }
1249  } catch (Exception e) {
1250  // We convert all exceptions from JSON parsing to our own exceptions.
1251  throw new InvalidProtocolBufferException(e.getMessage());
1252  }
1253  }
1254 
1255  void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException {
1256  try {
1257  JsonReader reader = new JsonReader(new StringReader(json));
1258  reader.setLenient(false);
1259  merge(jsonParser.parse(reader), builder);
1260  } catch (InvalidProtocolBufferException e) {
1261  throw e;
1262  } catch (Exception e) {
1263  // We convert all exceptions from JSON parsing to our own exceptions.
1264  throw new InvalidProtocolBufferException(e.getMessage());
1265  }
1266  }
1267 
1268  private interface WellKnownTypeParser {
1269  void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1271  }
1272 
1273  private static final Map<String, WellKnownTypeParser> wellKnownTypeParsers =
1275 
1276  private static Map<String, WellKnownTypeParser> buildWellKnownTypeParsers() {
1277  Map<String, WellKnownTypeParser> parsers = new HashMap<String, WellKnownTypeParser>();
1278  // Special-case Any.
1279  parsers.put(
1280  Any.getDescriptor().getFullName(),
1281  new WellKnownTypeParser() {
1282  @Override
1283  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1285  parser.mergeAny(json, builder);
1286  }
1287  });
1288  // Special-case wrapper types.
1289  WellKnownTypeParser wrappersPrinter =
1290  new WellKnownTypeParser() {
1291  @Override
1292  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1294  parser.mergeWrapper(json, builder);
1295  }
1296  };
1297  parsers.put(BoolValue.getDescriptor().getFullName(), wrappersPrinter);
1298  parsers.put(Int32Value.getDescriptor().getFullName(), wrappersPrinter);
1299  parsers.put(UInt32Value.getDescriptor().getFullName(), wrappersPrinter);
1300  parsers.put(Int64Value.getDescriptor().getFullName(), wrappersPrinter);
1301  parsers.put(UInt64Value.getDescriptor().getFullName(), wrappersPrinter);
1302  parsers.put(StringValue.getDescriptor().getFullName(), wrappersPrinter);
1303  parsers.put(BytesValue.getDescriptor().getFullName(), wrappersPrinter);
1304  parsers.put(FloatValue.getDescriptor().getFullName(), wrappersPrinter);
1305  parsers.put(DoubleValue.getDescriptor().getFullName(), wrappersPrinter);
1306  // Special-case Timestamp.
1307  parsers.put(
1308  Timestamp.getDescriptor().getFullName(),
1309  new WellKnownTypeParser() {
1310  @Override
1311  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1313  parser.mergeTimestamp(json, builder);
1314  }
1315  });
1316  // Special-case Duration.
1317  parsers.put(
1318  Duration.getDescriptor().getFullName(),
1319  new WellKnownTypeParser() {
1320  @Override
1321  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1323  parser.mergeDuration(json, builder);
1324  }
1325  });
1326  // Special-case FieldMask.
1327  parsers.put(
1328  FieldMask.getDescriptor().getFullName(),
1329  new WellKnownTypeParser() {
1330  @Override
1331  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1333  parser.mergeFieldMask(json, builder);
1334  }
1335  });
1336  // Special-case Struct.
1337  parsers.put(
1338  Struct.getDescriptor().getFullName(),
1339  new WellKnownTypeParser() {
1340  @Override
1341  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1343  parser.mergeStruct(json, builder);
1344  }
1345  });
1346  // Special-case ListValue.
1347  parsers.put(
1348  ListValue.getDescriptor().getFullName(),
1349  new WellKnownTypeParser() {
1350  @Override
1351  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1353  parser.mergeListValue(json, builder);
1354  }
1355  });
1356  // Special-case Value.
1357  parsers.put(
1358  Value.getDescriptor().getFullName(),
1359  new WellKnownTypeParser() {
1360  @Override
1361  public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
1363  parser.mergeValue(json, builder);
1364  }
1365  });
1366  return parsers;
1367  }
1368 
1369  private void merge(JsonElement json, Message.Builder builder)
1371  WellKnownTypeParser specialParser =
1372  wellKnownTypeParsers.get(builder.getDescriptorForType().getFullName());
1373  if (specialParser != null) {
1374  specialParser.merge(this, json, builder);
1375  return;
1376  }
1377  mergeMessage(json, builder, false);
1378  }
1379 
1380  // Maps from camel-case field names to FieldDescriptor.
1381  private final Map<Descriptor, Map<String, FieldDescriptor>> fieldNameMaps =
1382  new HashMap<Descriptor, Map<String, FieldDescriptor>>();
1383 
1384  private Map<String, FieldDescriptor> getFieldNameMap(Descriptor descriptor) {
1385  if (!fieldNameMaps.containsKey(descriptor)) {
1386  Map<String, FieldDescriptor> fieldNameMap = new HashMap<String, FieldDescriptor>();
1387  for (FieldDescriptor field : descriptor.getFields()) {
1388  fieldNameMap.put(field.getName(), field);
1389  fieldNameMap.put(field.getJsonName(), field);
1390  }
1391  fieldNameMaps.put(descriptor, fieldNameMap);
1392  return fieldNameMap;
1393  }
1394  return fieldNameMaps.get(descriptor);
1395  }
1396 
1397  private void mergeMessage(JsonElement json, Message.Builder builder, boolean skipTypeUrl)
1399  if (!(json instanceof JsonObject)) {
1400  throw new InvalidProtocolBufferException("Expect message object but got: " + json);
1401  }
1402  JsonObject object = (JsonObject) json;
1403  Map<String, FieldDescriptor> fieldNameMap = getFieldNameMap(builder.getDescriptorForType());
1404  for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
1405  if (skipTypeUrl && entry.getKey().equals("@type")) {
1406  continue;
1407  }
1408  FieldDescriptor field = fieldNameMap.get(entry.getKey());
1409  if (field == null) {
1410  if (ignoringUnknownFields) {
1411  continue;
1412  }
1414  "Cannot find field: "
1415  + entry.getKey()
1416  + " in message "
1417  + builder.getDescriptorForType().getFullName());
1418  }
1419  mergeField(field, entry.getValue(), builder);
1420  }
1421  }
1422 
1423  private void mergeAny(JsonElement json, Message.Builder builder)
1425  Descriptor descriptor = builder.getDescriptorForType();
1426  FieldDescriptor typeUrlField = descriptor.findFieldByName("type_url");
1427  FieldDescriptor valueField = descriptor.findFieldByName("value");
1428  // Validates type of the message. Note that we can't just cast the message
1429  // to com.google.protobuf.Any because it might be a DynamicMessage.
1430  if (typeUrlField == null
1431  || valueField == null
1432  || typeUrlField.getType() != FieldDescriptor.Type.STRING
1433  || valueField.getType() != FieldDescriptor.Type.BYTES) {
1434  throw new InvalidProtocolBufferException("Invalid Any type.");
1435  }
1436 
1437  if (!(json instanceof JsonObject)) {
1438  throw new InvalidProtocolBufferException("Expect message object but got: " + json);
1439  }
1440  JsonObject object = (JsonObject) json;
1441  if (object.entrySet().isEmpty()) {
1442  return; // builder never modified, so it will end up building the default instance of Any
1443  }
1444  JsonElement typeUrlElement = object.get("@type");
1445  if (typeUrlElement == null) {
1446  throw new InvalidProtocolBufferException("Missing type url when parsing: " + json);
1447  }
1448  String typeUrl = typeUrlElement.getAsString();
1449  Descriptor contentType = registry.getDescriptorForTypeUrl(typeUrl);
1450  if (contentType == null) {
1451  throw new InvalidProtocolBufferException("Cannot resolve type: " + typeUrl);
1452  }
1453  builder.setField(typeUrlField, typeUrl);
1454  Message.Builder contentBuilder =
1456  WellKnownTypeParser specialParser = wellKnownTypeParsers.get(contentType.getFullName());
1457  if (specialParser != null) {
1458  JsonElement value = object.get("value");
1459  if (value != null) {
1460  specialParser.merge(this, value, contentBuilder);
1461  }
1462  } else {
1463  mergeMessage(json, contentBuilder, true);
1464  }
1465  builder.setField(valueField, contentBuilder.build().toByteString());
1466  }
1467 
1468  private void mergeFieldMask(JsonElement json, Message.Builder builder)
1470  FieldMask value = FieldMaskUtil.fromJsonString(json.getAsString());
1471  builder.mergeFrom(value.toByteString());
1472  }
1473 
1474  private void mergeTimestamp(JsonElement json, Message.Builder builder)
1476  try {
1477  Timestamp value = Timestamps.parse(json.getAsString());
1478  builder.mergeFrom(value.toByteString());
1479  } catch (ParseException e) {
1480  throw new InvalidProtocolBufferException("Failed to parse timestamp: " + json);
1481  }
1482  }
1483 
1484  private void mergeDuration(JsonElement json, Message.Builder builder)
1486  try {
1487  Duration value = Durations.parse(json.getAsString());
1488  builder.mergeFrom(value.toByteString());
1489  } catch (ParseException e) {
1490  throw new InvalidProtocolBufferException("Failed to parse duration: " + json);
1491  }
1492  }
1493 
1494  private void mergeStruct(JsonElement json, Message.Builder builder)
1496  Descriptor descriptor = builder.getDescriptorForType();
1497  FieldDescriptor field = descriptor.findFieldByName("fields");
1498  if (field == null) {
1499  throw new InvalidProtocolBufferException("Invalid Struct type.");
1500  }
1501  mergeMapField(field, json, builder);
1502  }
1503 
1504  private void mergeListValue(JsonElement json, Message.Builder builder)
1506  Descriptor descriptor = builder.getDescriptorForType();
1507  FieldDescriptor field = descriptor.findFieldByName("values");
1508  if (field == null) {
1509  throw new InvalidProtocolBufferException("Invalid ListValue type.");
1510  }
1511  mergeRepeatedField(field, json, builder);
1512  }
1513 
1514  private void mergeValue(JsonElement json, Message.Builder builder)
1516  Descriptor type = builder.getDescriptorForType();
1517  if (json instanceof JsonPrimitive) {
1518  JsonPrimitive primitive = (JsonPrimitive) json;
1519  if (primitive.isBoolean()) {
1520  builder.setField(type.findFieldByName("bool_value"), primitive.getAsBoolean());
1521  } else if (primitive.isNumber()) {
1522  builder.setField(type.findFieldByName("number_value"), primitive.getAsDouble());
1523  } else {
1524  builder.setField(type.findFieldByName("string_value"), primitive.getAsString());
1525  }
1526  } else if (json instanceof JsonObject) {
1527  FieldDescriptor field = type.findFieldByName("struct_value");
1528  Message.Builder structBuilder = builder.newBuilderForField(field);
1529  merge(json, structBuilder);
1530  builder.setField(field, structBuilder.build());
1531  } else if (json instanceof JsonArray) {
1532  FieldDescriptor field = type.findFieldByName("list_value");
1533  Message.Builder listBuilder = builder.newBuilderForField(field);
1534  merge(json, listBuilder);
1535  builder.setField(field, listBuilder.build());
1536  } else if (json instanceof JsonNull) {
1537  builder.setField(
1538  type.findFieldByName("null_value"), NullValue.NULL_VALUE.getValueDescriptor());
1539  } else {
1540  throw new IllegalStateException("Unexpected json data: " + json);
1541  }
1542  }
1543 
1544  private void mergeWrapper(JsonElement json, Message.Builder builder)
1546  Descriptor type = builder.getDescriptorForType();
1547  FieldDescriptor field = type.findFieldByName("value");
1548  if (field == null) {
1549  throw new InvalidProtocolBufferException("Invalid wrapper type: " + type.getFullName());
1550  }
1551  builder.setField(field, parseFieldValue(field, json, builder));
1552  }
1553 
1554  private void mergeField(FieldDescriptor field, JsonElement json, Message.Builder builder)
1556  if (field.isRepeated()) {
1557  if (builder.getRepeatedFieldCount(field) > 0) {
1559  "Field " + field.getFullName() + " has already been set.");
1560  }
1561  } else {
1562  if (builder.hasField(field)) {
1564  "Field " + field.getFullName() + " has already been set.");
1565  }
1566  }
1567  if (field.isRepeated() && json instanceof JsonNull) {
1568  // We allow "null" as value for all field types and treat it as if the
1569  // field is not present.
1570  return;
1571  }
1572  if (field.isMapField()) {
1573  mergeMapField(field, json, builder);
1574  } else if (field.isRepeated()) {
1575  mergeRepeatedField(field, json, builder);
1576  } else if (field.getContainingOneof() != null) {
1577  mergeOneofField(field, json, builder);
1578  } else {
1579  Object value = parseFieldValue(field, json, builder);
1580  if (value != null) {
1581  // A field interpreted as "null" is means it's treated as absent.
1582  builder.setField(field, value);
1583  }
1584  }
1585  }
1586 
1587  private void mergeMapField(FieldDescriptor field, JsonElement json, Message.Builder builder)
1589  if (!(json instanceof JsonObject)) {
1590  throw new InvalidProtocolBufferException("Expect a map object but found: " + json);
1591  }
1592  Descriptor type = field.getMessageType();
1593  FieldDescriptor keyField = type.findFieldByName("key");
1594  FieldDescriptor valueField = type.findFieldByName("value");
1595  if (keyField == null || valueField == null) {
1596  throw new InvalidProtocolBufferException("Invalid map field: " + field.getFullName());
1597  }
1598  JsonObject object = (JsonObject) json;
1599  for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
1600  Message.Builder entryBuilder = builder.newBuilderForField(field);
1601  Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
1602  Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder);
1603  if (value == null) {
1604  if (ignoringUnknownFields && valueField.getType() == Type.ENUM) {
1605  continue;
1606  } else {
1607  throw new InvalidProtocolBufferException("Map value cannot be null.");
1608  }
1609  }
1610  entryBuilder.setField(keyField, key);
1611  entryBuilder.setField(valueField, value);
1612  builder.addRepeatedField(field, entryBuilder.build());
1613  }
1614  }
1615 
1616  private void mergeOneofField(FieldDescriptor field, JsonElement json, Message.Builder builder)
1618  Object value = parseFieldValue(field, json, builder);
1619  if (value == null) {
1620  // A field interpreted as "null" is means it's treated as absent.
1621  return;
1622  }
1623  if (builder.getOneofFieldDescriptor(field.getContainingOneof()) != null) {
1625  "Cannot set field "
1626  + field.getFullName()
1627  + " because another field "
1628  + builder.getOneofFieldDescriptor(field.getContainingOneof()).getFullName()
1629  + " belonging to the same oneof has already been set ");
1630  }
1631  builder.setField(field, value);
1632  }
1633 
1634  private void mergeRepeatedField(
1635  FieldDescriptor field, JsonElement json, Message.Builder builder)
1637  if (!(json instanceof JsonArray)) {
1638  throw new InvalidProtocolBufferException("Expect an array but found: " + json);
1639  }
1640  JsonArray array = (JsonArray) json;
1641  for (int i = 0; i < array.size(); ++i) {
1642  Object value = parseFieldValue(field, array.get(i), builder);
1643  if (value == null) {
1644  if (ignoringUnknownFields && field.getType() == Type.ENUM) {
1645  continue;
1646  } else {
1648  "Repeated field elements cannot be null in field: " + field.getFullName());
1649  }
1650  }
1651  builder.addRepeatedField(field, value);
1652  }
1653  }
1654 
1655  private int parseInt32(JsonElement json) throws InvalidProtocolBufferException {
1656  try {
1657  return Integer.parseInt(json.getAsString());
1658  } catch (Exception e) {
1659  // Fall through.
1660  }
1661  // JSON doesn't distinguish between integer values and floating point values so "1" and
1662  // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
1663  // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
1664  try {
1665  BigDecimal value = new BigDecimal(json.getAsString());
1666  return value.intValueExact();
1667  } catch (Exception e) {
1668  throw new InvalidProtocolBufferException("Not an int32 value: " + json);
1669  }
1670  }
1671 
1672  private long parseInt64(JsonElement json) throws InvalidProtocolBufferException {
1673  try {
1674  return Long.parseLong(json.getAsString());
1675  } catch (Exception e) {
1676  // Fall through.
1677  }
1678  // JSON doesn't distinguish between integer values and floating point values so "1" and
1679  // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
1680  // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
1681  try {
1682  BigDecimal value = new BigDecimal(json.getAsString());
1683  return value.longValueExact();
1684  } catch (Exception e) {
1685  throw new InvalidProtocolBufferException("Not an int64 value: " + json);
1686  }
1687  }
1688 
1689  private int parseUint32(JsonElement json) throws InvalidProtocolBufferException {
1690  try {
1691  long result = Long.parseLong(json.getAsString());
1692  if (result < 0 || result > 0xFFFFFFFFL) {
1693  throw new InvalidProtocolBufferException("Out of range uint32 value: " + json);
1694  }
1695  return (int) result;
1696  } catch (InvalidProtocolBufferException e) {
1697  throw e;
1698  } catch (Exception e) {
1699  // Fall through.
1700  }
1701  // JSON doesn't distinguish between integer values and floating point values so "1" and
1702  // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
1703  // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
1704  try {
1705  BigDecimal decimalValue = new BigDecimal(json.getAsString());
1706  BigInteger value = decimalValue.toBigIntegerExact();
1707  if (value.signum() < 0 || value.compareTo(new BigInteger("FFFFFFFF", 16)) > 0) {
1708  throw new InvalidProtocolBufferException("Out of range uint32 value: " + json);
1709  }
1710  return value.intValue();
1711  } catch (InvalidProtocolBufferException e) {
1712  throw e;
1713  } catch (Exception e) {
1714  throw new InvalidProtocolBufferException("Not an uint32 value: " + json);
1715  }
1716  }
1717 
1718  private static final BigInteger MAX_UINT64 = new BigInteger("FFFFFFFFFFFFFFFF", 16);
1719 
1720  private long parseUint64(JsonElement json) throws InvalidProtocolBufferException {
1721  try {
1722  BigDecimal decimalValue = new BigDecimal(json.getAsString());
1723  BigInteger value = decimalValue.toBigIntegerExact();
1724  if (value.compareTo(BigInteger.ZERO) < 0 || value.compareTo(MAX_UINT64) > 0) {
1725  throw new InvalidProtocolBufferException("Out of range uint64 value: " + json);
1726  }
1727  return value.longValue();
1728  } catch (InvalidProtocolBufferException e) {
1729  throw e;
1730  } catch (Exception e) {
1731  throw new InvalidProtocolBufferException("Not an uint64 value: " + json);
1732  }
1733  }
1734 
1735  private boolean parseBool(JsonElement json) throws InvalidProtocolBufferException {
1736  if (json.getAsString().equals("true")) {
1737  return true;
1738  }
1739  if (json.getAsString().equals("false")) {
1740  return false;
1741  }
1742  throw new InvalidProtocolBufferException("Invalid bool value: " + json);
1743  }
1744 
1745  private static final double EPSILON = 1e-6;
1746 
1747  private float parseFloat(JsonElement json) throws InvalidProtocolBufferException {
1748  if (json.getAsString().equals("NaN")) {
1749  return Float.NaN;
1750  } else if (json.getAsString().equals("Infinity")) {
1751  return Float.POSITIVE_INFINITY;
1752  } else if (json.getAsString().equals("-Infinity")) {
1753  return Float.NEGATIVE_INFINITY;
1754  }
1755  try {
1756  // We don't use Float.parseFloat() here because that function simply
1757  // accepts all double values. Here we parse the value into a Double
1758  // and do explicit range check on it.
1759  double value = Double.parseDouble(json.getAsString());
1760  // When a float value is printed, the printed value might be a little
1761  // larger or smaller due to precision loss. Here we need to add a bit
1762  // of tolerance when checking whether the float value is in range.
1763  if (value > Float.MAX_VALUE * (1.0 + EPSILON)
1764  || value < -Float.MAX_VALUE * (1.0 + EPSILON)) {
1765  throw new InvalidProtocolBufferException("Out of range float value: " + json);
1766  }
1767  return (float) value;
1768  } catch (InvalidProtocolBufferException e) {
1769  throw e;
1770  } catch (Exception e) {
1771  throw new InvalidProtocolBufferException("Not a float value: " + json);
1772  }
1773  }
1774 
1775  private static final BigDecimal MORE_THAN_ONE = new BigDecimal(String.valueOf(1.0 + EPSILON));
1776  // When a float value is printed, the printed value might be a little
1777  // larger or smaller due to precision loss. Here we need to add a bit
1778  // of tolerance when checking whether the float value is in range.
1779  private static final BigDecimal MAX_DOUBLE =
1780  new BigDecimal(String.valueOf(Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
1781  private static final BigDecimal MIN_DOUBLE =
1782  new BigDecimal(String.valueOf(-Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
1783 
1784  private double parseDouble(JsonElement json) throws InvalidProtocolBufferException {
1785  if (json.getAsString().equals("NaN")) {
1786  return Double.NaN;
1787  } else if (json.getAsString().equals("Infinity")) {
1788  return Double.POSITIVE_INFINITY;
1789  } else if (json.getAsString().equals("-Infinity")) {
1790  return Double.NEGATIVE_INFINITY;
1791  }
1792  try {
1793  // We don't use Double.parseDouble() here because that function simply
1794  // accepts all values. Here we parse the value into a BigDecimal and do
1795  // explicit range check on it.
1796  BigDecimal value = new BigDecimal(json.getAsString());
1797  if (value.compareTo(MAX_DOUBLE) > 0 || value.compareTo(MIN_DOUBLE) < 0) {
1798  throw new InvalidProtocolBufferException("Out of range double value: " + json);
1799  }
1800  return value.doubleValue();
1801  } catch (InvalidProtocolBufferException e) {
1802  throw e;
1803  } catch (Exception e) {
1804  throw new InvalidProtocolBufferException("Not an double value: " + json);
1805  }
1806  }
1807 
1808  private String parseString(JsonElement json) {
1809  return json.getAsString();
1810  }
1811 
1812  private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException {
1813  try {
1814  return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString()));
1815  } catch (IllegalArgumentException e) {
1816  return ByteString.copyFrom(BaseEncoding.base64Url().decode(json.getAsString()));
1817  }
1818  }
1819 
1820  private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
1822  String value = json.getAsString();
1823  EnumValueDescriptor result = enumDescriptor.findValueByName(value);
1824  if (result == null) {
1825  // Try to interpret the value as a number.
1826  try {
1827  int numericValue = parseInt32(json);
1828  if (enumDescriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3) {
1829  result = enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue);
1830  } else {
1831  result = enumDescriptor.findValueByNumber(numericValue);
1832  }
1833  } catch (InvalidProtocolBufferException e) {
1834  // Fall through. This exception is about invalid int32 value we get from parseInt32() but
1835  // that's not the exception we want the user to see. Since result == null, we will throw
1836  // an exception later.
1837  }
1838 
1839  if (result == null && !ignoringUnknownFields) {
1841  "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
1842  }
1843  }
1844  return result;
1845  }
1846 
1847  private Object parseFieldValue(FieldDescriptor field, JsonElement json, Message.Builder builder)
1849  if (json instanceof JsonNull) {
1850  if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
1851  && field.getMessageType().getFullName().equals(Value.getDescriptor().getFullName())) {
1852  // For every other type, "null" means absence, but for the special
1853  // Value message, it means the "null_value" field has been set.
1854  Value value = Value.newBuilder().setNullValueValue(0).build();
1855  return builder.newBuilderForField(field).mergeFrom(value.toByteString()).build();
1856  } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM
1857  && field.getEnumType().getFullName().equals(NullValue.getDescriptor().getFullName())) {
1858  // If the type of the field is a NullValue, then the value should be explicitly set.
1859  return field.getEnumType().findValueByNumber(0);
1860  }
1861  return null;
1862  }
1863  switch (field.getType()) {
1864  case INT32:
1865  case SINT32:
1866  case SFIXED32:
1867  return parseInt32(json);
1868 
1869  case INT64:
1870  case SINT64:
1871  case SFIXED64:
1872  return parseInt64(json);
1873 
1874  case BOOL:
1875  return parseBool(json);
1876 
1877  case FLOAT:
1878  return parseFloat(json);
1879 
1880  case DOUBLE:
1881  return parseDouble(json);
1882 
1883  case UINT32:
1884  case FIXED32:
1885  return parseUint32(json);
1886 
1887  case UINT64:
1888  case FIXED64:
1889  return parseUint64(json);
1890 
1891  case STRING:
1892  return parseString(json);
1893 
1894  case BYTES:
1895  return parseBytes(json);
1896 
1897  case ENUM:
1898  return parseEnum(field.getEnumType(), json);
1899 
1900  case MESSAGE:
1901  case GROUP:
1902  if (currentDepth >= recursionLimit) {
1903  throw new InvalidProtocolBufferException("Hit recursion limit.");
1904  }
1905  ++currentDepth;
1906  Message.Builder subBuilder = builder.newBuilderForField(field);
1907  merge(json, subBuilder);
1908  --currentDepth;
1909  return subBuilder.build();
1910 
1911  default:
1912  throw new InvalidProtocolBufferException("Invalid field type: " + field.getType());
1913  }
1914  }
1915  }
1916 }
com.google.protobuf.Descriptors
Definition: Descriptors.java:80
Map
struct Map Map
Definition: php/ext/google/protobuf/protobuf.h:648
com.google.protobuf.util.JsonFormat.ParserImpl.parseString
String parseString(JsonElement json)
Definition: JsonFormat.java:1808
com.google.protobuf.util.JsonFormat.ParserImpl.parseEnum
EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
Definition: JsonFormat.java:1820
com.google.protobuf.util.JsonFormat.PrinterImpl.WellKnownTypePrinter
Definition: JsonFormat.java:698
com.google.protobuf.util.JsonFormat.PrinterImpl.GsonHolder
Definition: JsonFormat.java:656
com.google.protobuf.util.JsonFormat.ParserImpl.mergeDuration
void mergeDuration(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1484
com.google.protobuf.MessageOrBuilder.getField
Object getField(Descriptors.FieldDescriptor field)
com.google.protobuf.util.JsonFormat.Parser.merge
void merge(String json, Message.Builder builder)
Definition: JsonFormat.java:404
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
com.google.protobuf.Descriptors.FileDescriptor.getDependencies
List< FileDescriptor > getDependencies()
Definition: Descriptors.java:146
com.google.protobuf.util.JsonFormat.PrinterImpl.generator
final TextGenerator generator
Definition: JsonFormat.java:650
com.google.protobuf.util.JsonFormat.TypeRegistry.newBuilder
static Builder newBuilder()
Definition: JsonFormat.java:446
com.google.protobuf.util.JsonFormat.ParserImpl.parseBytes
ByteString parseBytes(JsonElement json)
Definition: JsonFormat.java:1812
com.google.protobuf::Any
com.google.protobuf.util.JsonFormat.unsignedToString
static String unsignedToString(final int value)
Definition: JsonFormat.java:1193
com.google.protobuf.util.JsonFormat.ParserImpl.parseBool
boolean parseBool(JsonElement json)
Definition: JsonFormat.java:1735
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.addFile
void addFile(FileDescriptor file)
Definition: JsonFormat.java:513
BoolValue
struct BoolValue BoolValue
Definition: php/ext/google/protobuf/protobuf.h:626
com.google.protobuf.util.JsonFormat.ParserImpl.mergeAny
void mergeAny(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1423
com.google.protobuf.util.JsonFormat.CompactTextGenerator
Definition: JsonFormat.java:559
com.google.protobuf::ListValue
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.atStartOfLine
boolean atStartOfLine
Definition: JsonFormat.java:586
com.google.protobuf.util.JsonFormat.parser
static Parser parser()
Definition: JsonFormat.java:356
com.google.protobuf.util.JsonFormat.ParserImpl.WellKnownTypeParser.merge
void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.addMessage
void addMessage(Descriptor message)
Definition: JsonFormat.java:526
com.google.protobuf.util.JsonFormat.PrinterImpl.includingDefaultValueFields
final Set< FieldDescriptor > includingDefaultValueFields
Definition: JsonFormat.java:646
com.google.protobuf.util.JsonFormat.ParserImpl.mergeRepeatedField
void mergeRepeatedField(FieldDescriptor field, JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1634
com.google.protobuf.util.JsonFormat.Printer.includingDefaultValueFields
Set< FieldDescriptor > includingDefaultValueFields
Definition: JsonFormat.java:129
com.google.protobuf.util.JsonFormat.Parser.ignoringUnknownFields
final boolean ignoringUnknownFields
Definition: JsonFormat.java:365
com.google.protobuf.util.JsonFormat.ParserImpl.parseUint64
long parseUint64(JsonElement json)
Definition: JsonFormat.java:1720
com.google.protobuf.util.JsonFormat.Printer.includingDefaultValueFields
Printer includingDefaultValueFields(Set< FieldDescriptor > fieldsToAlwaysOutput)
Definition: JsonFormat.java:221
com.google.protobuf.util.JsonFormat.Printer.preservingProtoFieldNames
Printer preservingProtoFieldNames()
Definition: JsonFormat.java:250
com.google.protobuf.util.JsonFormat.Parser.recursionLimit
final int recursionLimit
Definition: JsonFormat.java:366
types
GLsizei GLenum GLenum * types
Definition: glcorearb.h:4177
indent
static int indent(upb_textprinter *p)
Definition: php/ext/google/protobuf/upb.c:8400
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.PrettyTextGenerator
PrettyTextGenerator(final Appendable output)
Definition: JsonFormat.java:588
com.google.protobuf.util.JsonFormat.printer
static Printer printer()
Definition: JsonFormat.java:109
Json::booleanValue
@ booleanValue
bool value
Definition: json.h:469
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.indent
void indent()
Definition: JsonFormat.java:598
com.google.protobuf.util.Durations.parse
static Duration parse(String value)
Definition: Durations.java:241
com.google.protobuf.util.JsonFormat.Printer.print
String print(MessageOrBuilder message)
Definition: JsonFormat.java:339
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.files
final Set< String > files
Definition: JsonFormat.java:539
com.google.protobuf.util.JsonFormat.PrinterImpl.printWrapper
void printWrapper(MessageOrBuilder message)
Definition: JsonFormat.java:834
com.google.protobuf.util.JsonFormat.Printer.checkUnsetPrintingEnumsAsInts
void checkUnsetPrintingEnumsAsInts()
Definition: JsonFormat.java:208
com.google.protobuf.Descriptors.FileDescriptor.getFullName
String getFullName()
Definition: Descriptors.java:108
com.google.protobuf.util.JsonFormat.PrinterImpl.printAny
void printAny(MessageOrBuilder message)
Definition: JsonFormat.java:791
com.google.protobuf.util.JsonFormat.Printer.printingEnumsAsInts
final boolean printingEnumsAsInts
Definition: JsonFormat.java:132
com.google.protobuf.util.JsonFormat.ParserImpl.EPSILON
static final double EPSILON
Definition: JsonFormat.java:1745
getName
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
com.google.protobuf.util.JsonFormat.ParserImpl.mergeWrapper
void mergeWrapper(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1544
com.google.protobuf.util.JsonFormat.ParserImpl.mergeListValue
void mergeListValue(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1504
com.google.protobuf.util.JsonFormat.Parser.usingTypeRegistry
Parser usingTypeRegistry(TypeRegistry registry)
Definition: JsonFormat.java:383
com.google.protobuf.util.JsonFormat.ParserImpl.mergeTimestamp
void mergeTimestamp(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1474
com.google.protobuf.util.JsonFormat.ParserImpl.mergeOneofField
void mergeOneofField(FieldDescriptor field, JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1616
com.google.protobuf.util.JsonFormat.PrettyTextGenerator
Definition: JsonFormat.java:583
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.write
void write(final CharSequence data)
Definition: JsonFormat.java:628
com.google.protobuf.DynamicMessage.getParserForType
Parser< DynamicMessage > getParserForType()
Definition: DynamicMessage.java:283
com.google.protobuf::BoolValue
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.outdent
void outdent()
Definition: JsonFormat.java:604
FieldMask
struct FieldMask FieldMask
Definition: php/ext/google/protobuf/protobuf.h:640
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.Builder
Builder()
Definition: JsonFormat.java:472
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
com.google.protobuf::Int32Value
com.google.protobuf.Descriptors.FileDescriptor.Syntax.PROTO3
PROTO3
Definition: Descriptors.java:159
com.google.protobuf.util.JsonFormat.PrinterImpl.printFieldMask
void printFieldMask(MessageOrBuilder message)
Definition: JsonFormat.java:866
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
com.google.protobuf.util.Durations.toString
static String toString(Duration duration)
Definition: Durations.java:214
com.google.protobuf.util.JsonFormat.PrinterImpl.buildWellKnownTypePrinters
static Map< String, WellKnownTypePrinter > buildWellKnownTypePrinters()
Definition: JsonFormat.java:705
com.google.protobuf.util.JsonFormat.PrinterImpl.printSingleFieldValue
void printSingleFieldValue(FieldDescriptor field, Object value)
Definition: JsonFormat.java:1050
com.google.protobuf.util.JsonFormat.ParserImpl.recursionLimit
final int recursionLimit
Definition: JsonFormat.java:1224
com.google.protobuf.Descriptors.FileDescriptor.getMessageTypes
List< Descriptor > getMessageTypes()
Definition: Descriptors.java:126
com.google.protobuf.Descriptors.FieldDescriptor.Type
Definition: Descriptors.java:1215
com.google.protobuf.util.JsonFormat.PrinterImpl.WellKnownTypePrinter.print
void print(PrinterImpl printer, MessageOrBuilder message)
com.google.protobuf.util.JsonFormat.PrinterImpl.printRepeatedFieldValue
void printRepeatedFieldValue(FieldDescriptor field, Object value)
Definition: JsonFormat.java:980
com.google.protobuf.util.JsonFormat.Printer.checkUnsetIncludingDefaultValueFields
void checkUnsetIncludingDefaultValueFields()
Definition: JsonFormat.java:237
com.google.protobuf.util.JsonFormat.Parser.Parser
Parser(TypeRegistry registry, boolean ignoreUnknownFields, int recursionLimit)
Definition: JsonFormat.java:371
com.google.protobuf.util.JsonFormat.ParserImpl.MORE_THAN_ONE
static final BigDecimal MORE_THAN_ONE
Definition: JsonFormat.java:1775
com.google.protobuf.Descriptors.Descriptor.getFullName
String getFullName()
Definition: Descriptors.java:675
com.google.protobuf.util.JsonFormat.ParserImpl.currentDepth
int currentDepth
Definition: JsonFormat.java:1225
com.google.protobuf.util.JsonFormat.unsignedToString
static String unsignedToString(final long value)
Definition: JsonFormat.java:1202
com.google.protobuf.util.JsonFormat.ParserImpl.mergeMessage
void mergeMessage(JsonElement json, Message.Builder builder, boolean skipTypeUrl)
Definition: JsonFormat.java:1397
testing::internal::Double
FloatingPoint< double > Double
Definition: gtest-internal.h:429
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder
Definition: JsonFormat.java:471
NullValue
NullValue
Definition: struct.pb.h:83
com.google.protobuf::Value
com.google.protobuf.util.Durations
Definition: Durations.java:54
com.google.protobuf.util.JsonFormat.ParserImpl.wellKnownTypeParsers
static final Map< String, WellKnownTypeParser > wellKnownTypeParsers
Definition: JsonFormat.java:1273
com.google.protobuf.util.JsonFormat.CompactTextGenerator.outdent
void outdent()
Definition: JsonFormat.java:572
com.google.protobuf.util.JsonFormat.TypeRegistry.TypeRegistry
TypeRegistry(Map< String, Descriptor > types)
Definition: JsonFormat.java:465
com.google.protobuf.DynamicMessage.newBuilderForType
Builder newBuilderForType()
Definition: DynamicMessage.java:273
Timestamp
struct Timestamp Timestamp
Definition: php/ext/google/protobuf/protobuf.h:663
com.google.protobuf.Descriptors.FieldDescriptor.Type.BYTES
BYTES
Definition: Descriptors.java:1227
com.google.protobuf.util.JsonFormat.ParserImpl.fieldNameMaps
final Map< Descriptor, Map< String, FieldDescriptor > > fieldNameMaps
Definition: JsonFormat.java:1381
com.google.protobuf.util.JsonFormat.getTypeName
static String getTypeName(String typeUrl)
Definition: JsonFormat.java:1212
com.google.protobuf.Descriptors.FieldDescriptor.JavaType.ENUM
ENUM
Definition: Descriptors.java:1270
com.google.protobuf.util.JsonFormat
Definition: JsonFormat.java:101
com.google.protobuf.util.JsonFormat.PrinterImpl.preservingProtoFieldNames
final boolean preservingProtoFieldNames
Definition: JsonFormat.java:647
com.google.protobuf.Descriptors.FieldDescriptor.getType
Type getType()
Definition: Descriptors.java:1014
com.google.protobuf.util.JsonFormat.PrinterImpl.printingEnumsAsInts
final boolean printingEnumsAsInts
Definition: JsonFormat.java:648
com.google.protobuf.util.JsonFormat.Printer.omittingInsignificantWhitespace
final boolean omittingInsignificantWhitespace
Definition: JsonFormat.java:131
com.google.protobuf.util.JsonFormat.PrinterImpl.toByteString
ByteString toByteString(MessageOrBuilder message)
Definition: JsonFormat.java:845
com.google.protobuf.Descriptors.OneofDescriptor
Definition: Descriptors.java:2597
com.google.protobuf.Message.Builder
Definition: Message.java:104
com.google.protobuf.util.JsonFormat.Printer.omittingInsignificantWhitespace
Printer omittingInsignificantWhitespace()
Definition: JsonFormat.java:279
com.google.protobuf.util.JsonFormat.JsonFormat
JsonFormat()
Definition: JsonFormat.java:104
testing::internal::Float
FloatingPoint< float > Float
Definition: gtest-internal.h:428
com.google.protobuf.util.JsonFormat.PrinterImpl.sortingMapKeys
final boolean sortingMapKeys
Definition: JsonFormat.java:649
com.google.protobuf.util.JsonFormat.PrinterImpl
Definition: JsonFormat.java:643
ListValue
struct ListValue ListValue
Definition: php/ext/google/protobuf/protobuf.h:646
com.google.protobuf.util.Timestamps.parse
static Timestamp parse(String value)
Definition: Timestamps.java:232
com.google.protobuf.util.JsonFormat.ParserImpl.MAX_UINT64
static final BigInteger MAX_UINT64
Definition: JsonFormat.java:1718
com.google.protobuf.util.FieldMaskUtil.toJsonString
static String toJsonString(FieldMask fieldMask)
Definition: FieldMaskUtil.java:153
com.google.protobuf.util.JsonFormat.ParserImpl.MIN_DOUBLE
static final BigDecimal MIN_DOUBLE
Definition: JsonFormat.java:1781
com.google.protobuf.util.JsonFormat.PrinterImpl.alwaysOutputDefaultValueFields
final boolean alwaysOutputDefaultValueFields
Definition: JsonFormat.java:645
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.build
TypeRegistry build()
Definition: JsonFormat.java:506
com.google.protobuf.DynamicMessage.getDefaultInstance
static DynamicMessage getDefaultInstance(Descriptor type)
Definition: DynamicMessage.java:78
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.print
void print(final CharSequence text)
Definition: JsonFormat.java:614
com.google.protobuf.Descriptors.FieldDescriptor.JavaType
Definition: Descriptors.java:1262
com.google.protobuf.util.JsonFormat.ParserImpl.parseInt32
int parseInt32(JsonElement json)
Definition: JsonFormat.java:1655
Int32Value
struct Int32Value Int32Value
Definition: php/ext/google/protobuf/protobuf.h:643
com.google.protobuf.util.JsonFormat.ParserImpl.registry
final TypeRegistry registry
Definition: JsonFormat.java:1221
com.google.protobuf.util.JsonFormat.Printer.Printer
Printer(TypeRegistry registry, boolean alwaysOutputDefaultValueFields, Set< FieldDescriptor > includingDefaultValueFields, boolean preservingProtoFieldNames, boolean omittingInsignificantWhitespace, boolean printingEnumsAsInts, boolean sortingMapKeys)
Definition: JsonFormat.java:135
com.google.protobuf.util.JsonFormat.Printer.registry
final TypeRegistry registry
Definition: JsonFormat.java:119
benchmark::o1
@ o1
Definition: benchmark.h:375
com.google.protobuf.MessageOrBuilder
Definition: MessageOrBuilder.java:42
com.google.protobuf.Descriptors.EnumDescriptor
Definition: Descriptors.java:1583
com.google.protobuf.util.JsonFormat.ParserImpl.merge
void merge(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1369
size
#define size
Definition: glcorearb.h:2944
com.google.protobuf.util.JsonFormat.Parser.merge
void merge(Reader json, Message.Builder builder)
Definition: JsonFormat.java:417
UInt64Value
struct UInt64Value UInt64Value
Definition: php/ext/google/protobuf/protobuf.h:666
com.google.protobuf.util.JsonFormat.ParserImpl.parseFieldValue
Object parseFieldValue(FieldDescriptor field, JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1847
com.google.protobuf.util.JsonFormat.PrinterImpl.printDuration
void printDuration(MessageOrBuilder message)
Definition: JsonFormat.java:860
tests.google.protobuf.internal.message_test.cmp
cmp
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:61
com.google.protobuf.util.Timestamps.toString
static String toString(Timestamp timestamp)
Definition: Timestamps.java:203
com.google.protobuf.Descriptors.FileDescriptor.Syntax
Definition: Descriptors.java:156
com.google.protobuf.util.JsonFormat.PrinterImpl.registry
final TypeRegistry registry
Definition: JsonFormat.java:644
com.google.protobuf.util.JsonFormat.ParserImpl.parseDouble
double parseDouble(JsonElement json)
Definition: JsonFormat.java:1784
com.google.protobuf.util.JsonFormat.PrinterImpl.gson
final Gson gson
Definition: JsonFormat.java:652
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
com.google.protobuf.Descriptors.FieldDescriptor.Type.STRING
STRING
Definition: Descriptors.java:1224
com.google.protobuf.util.JsonFormat.ParserImpl.MAX_DOUBLE
static final BigDecimal MAX_DOUBLE
Definition: JsonFormat.java:1779
StringValue
struct StringValue StringValue
Definition: php/ext/google/protobuf/protobuf.h:660
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
com.google.protobuf::StringValue
com.google.protobuf.util.JsonFormat.Parser.ignoringUnknownFields
Parser ignoringUnknownFields()
Definition: JsonFormat.java:394
com.google.protobuf.util.JsonFormat.Printer.usingTypeRegistry
Printer usingTypeRegistry(TypeRegistry registry)
Definition: JsonFormat.java:158
com.google.protobuf.util.JsonFormat.PrinterImpl.printTimestamp
void printTimestamp(MessageOrBuilder message)
Definition: JsonFormat.java:854
com.google.protobuf.util.JsonFormat.Printer.sortingMapKeys
final boolean sortingMapKeys
Definition: JsonFormat.java:133
com.google.protobuf.util.JsonFormat.ParserImpl.mergeFieldMask
void mergeFieldMask(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1468
com.google.protobuf.util.JsonFormat.ParserImpl.mergeValue
void mergeValue(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1514
com.google.protobuf.util.FieldMaskUtil
Definition: FieldMaskUtil.java:52
com.google.protobuf::DoubleValue
i
int i
Definition: gmock-matchers_test.cc:764
com.google.protobuf.util.JsonFormat.ParserImpl.parseUint32
int parseUint32(JsonElement json)
Definition: JsonFormat.java:1689
com.google.protobuf.util.JsonFormat.ParserImpl.ignoringUnknownFields
final boolean ignoringUnknownFields
Definition: JsonFormat.java:1223
com.google.protobuf.util.JsonFormat.logger
static final Logger logger
Definition: JsonFormat.java:102
java
com.google.protobuf.Descriptors.Descriptor
Definition: Descriptors.java:629
FloatValue
struct FloatValue FloatValue
Definition: php/ext/google/protobuf/protobuf.h:641
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
com.google.protobuf.util.JsonFormat.ParserImpl.jsonParser
final JsonParser jsonParser
Definition: JsonFormat.java:1222
Int64Value
struct Int64Value Int64Value
Definition: php/ext/google/protobuf/protobuf.h:644
com.google.protobuf.util.JsonFormat.ParserImpl.mergeField
void mergeField(FieldDescriptor field, JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1554
com.google.protobuf.util.JsonFormat.PrinterImpl.printMapFieldValue
void printMapFieldValue(FieldDescriptor field, Object value)
Definition: JsonFormat.java:995
com.google.protobuf.util.JsonFormat.CompactTextGenerator.output
final Appendable output
Definition: JsonFormat.java:560
Any
struct Any Any
Definition: php/ext/google/protobuf/protobuf.h:624
type
GLenum type
Definition: glcorearb.h:2695
com.google.protobuf.util.JsonFormat.Parser.registry
final TypeRegistry registry
Definition: JsonFormat.java:364
com.google.protobuf::Duration
com.google.protobuf.util.JsonFormat.Printer.alwaysOutputDefaultValueFields
boolean alwaysOutputDefaultValueFields
Definition: JsonFormat.java:128
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.indent
final StringBuilder indent
Definition: JsonFormat.java:585
com.google.protobuf.util.JsonFormat.PrettyTextGenerator.output
final Appendable output
Definition: JsonFormat.java:584
com.google.protobuf.util.JsonFormat.Printer
Definition: JsonFormat.java:118
print
static unsigned char * print(const cJSON *const item, cJSON_bool format, const internal_hooks *const hooks)
Definition: cJSON.c:1074
com.google.protobuf.Descriptors.Descriptor.getNestedTypes
List< Descriptor > getNestedTypes()
Definition: Descriptors.java:711
com.google.protobuf::UInt64Value
com.google.protobuf.util.JsonFormat.ParserImpl.getFieldNameMap
Map< String, FieldDescriptor > getFieldNameMap(Descriptor descriptor)
Definition: JsonFormat.java:1384
com.google.protobuf.util.JsonFormat.CompactTextGenerator.CompactTextGenerator
CompactTextGenerator(final Appendable output)
Definition: JsonFormat.java:562
Duration
struct Duration Duration
Definition: php/ext/google/protobuf/protobuf.h:631
DoubleValue
struct DoubleValue DoubleValue
Definition: php/ext/google/protobuf/protobuf.h:630
com.google.protobuf.util.JsonFormat.PrinterImpl.printStruct
void printStruct(MessageOrBuilder message)
Definition: JsonFormat.java:872
com.google.protobuf.util.JsonFormat.Printer.preservingProtoFieldNames
final boolean preservingProtoFieldNames
Definition: JsonFormat.java:130
com.google.protobuf.util.JsonFormat.PrinterImpl.blankOrSpace
final CharSequence blankOrSpace
Definition: JsonFormat.java:653
com.google.protobuf.util.JsonFormat.CompactTextGenerator.indent
void indent()
Definition: JsonFormat.java:568
com.google.protobuf.util.JsonFormat.TypeRegistry.EmptyTypeRegistryHolder
Definition: JsonFormat.java:437
com.google.protobuf.util.JsonFormat.PrinterImpl.blankOrNewLine
final CharSequence blankOrNewLine
Definition: JsonFormat.java:654
size
GLsizeiptr size
Definition: glcorearb.h:2943
com.google.protobuf.util.Timestamps
Definition: Timestamps.java:54
com.google.protobuf.DynamicMessage
Definition: DynamicMessage.java:51
com.google.protobuf.util.JsonFormat.ParserImpl
Definition: JsonFormat.java:1220
com.google.protobuf.util.JsonFormat.Printer.includingDefaultValueFields
Printer includingDefaultValueFields()
Definition: JsonFormat.java:178
com.google.protobuf.util.JsonFormat.TypeRegistry
Definition: JsonFormat.java:436
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.add
Builder add(Iterable< Descriptor > messageTypes)
Definition: JsonFormat.java:492
com.google.protobuf::BytesValue
com.google
com
com.google.protobuf.util.JsonFormat.TypeRegistry.EmptyTypeRegistryHolder.EMPTY
static final TypeRegistry EMPTY
Definition: JsonFormat.java:438
com.google.protobuf.util.JsonFormat.PrinterImpl.GsonHolder.DEFAULT_GSON
static final Gson DEFAULT_GSON
Definition: JsonFormat.java:657
com.google.protobuf.util.JsonFormat.PrinterImpl.printSingleFieldValue
void printSingleFieldValue(final FieldDescriptor field, final Object value, boolean alwaysWithQuotes)
Definition: JsonFormat.java:1060
com.google.protobuf.util.JsonFormat.Parser
Definition: JsonFormat.java:363
UInt32Value
struct UInt32Value UInt32Value
Definition: php/ext/google/protobuf/protobuf.h:665
Struct
struct Struct Struct
Definition: php/ext/google/protobuf/protobuf.h:661
com.google.protobuf.util.JsonFormat.ParserImpl.mergeStruct
void mergeStruct(JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1494
com.google.protobuf.util.FieldMaskUtil.fromJsonString
static FieldMask fromJsonString(String value)
Definition: FieldMaskUtil.java:168
BytesValue
struct BytesValue BytesValue
Definition: php/ext/google/protobuf/protobuf.h:627
com.google.protobuf.util.JsonFormat.PrinterImpl.wellKnownTypePrinters
static final Map< String, WellKnownTypePrinter > wellKnownTypePrinters
Definition: JsonFormat.java:702
com.google.protobuf.util.JsonFormat.ParserImpl.buildWellKnownTypeParsers
static Map< String, WellKnownTypeParser > buildWellKnownTypeParsers()
Definition: JsonFormat.java:1276
com.google.protobuf::UInt32Value
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
com.google.protobuf.InvalidProtocolBufferException
Definition: InvalidProtocolBufferException.java:41
com.google.protobuf.util.JsonFormat.Printer.printingEnumsAsInts
Printer printingEnumsAsInts()
Definition: JsonFormat.java:196
com.google.protobuf.util.JsonFormat.TypeRegistry.Builder.add
Builder add(Descriptor messageType)
Definition: JsonFormat.java:479
com.google.protobuf.util.JsonFormat.TypeRegistry.types
final Map< String, Descriptor > types
Definition: JsonFormat.java:463
com.google.protobuf.Descriptors.EnumValueDescriptor
Definition: Descriptors.java:1774
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
Builder
struct Builder Builder
Definition: ruby/ext/google/protobuf_c/protobuf.h:67
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
com.google.protobuf.util.JsonFormat.ParserImpl.WellKnownTypeParser
Definition: JsonFormat.java:1268
com.google.protobuf.Descriptors.FileDescriptor
Definition: Descriptors.java:87
com.google.protobuf.util.JsonFormat.TypeRegistry.find
Descriptor find(String name)
Definition: JsonFormat.java:454
com.google.protobuf.util.JsonFormat.ParserImpl.mergeMapField
void mergeMapField(FieldDescriptor field, JsonElement json, Message.Builder builder)
Definition: JsonFormat.java:1587
com.google.protobuf.util.JsonFormat.PrinterImpl.printField
void printField(FieldDescriptor field, Object value)
Definition: JsonFormat.java:964
com.google.protobuf.util.JsonFormat.PrinterImpl.printListValue
void printListValue(MessageOrBuilder message)
Definition: JsonFormat.java:902
com.google.protobuf.util.JsonFormat.CompactTextGenerator.print
void print(final CharSequence text)
Definition: JsonFormat.java:576
com.google.protobuf.util.JsonFormat.ParserImpl.parseInt64
long parseInt64(JsonElement json)
Definition: JsonFormat.java:1672
com.google.protobuf.util.JsonFormat.Parser.DEFAULT_RECURSION_LIMIT
static final int DEFAULT_RECURSION_LIMIT
Definition: JsonFormat.java:369
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
com.google.protobuf.Message.Builder.newBuilderForField
Builder newBuilderForField(Descriptors.FieldDescriptor field)
com.google.protobuf.util.JsonFormat.PrinterImpl.print
void print(MessageOrBuilder message, String typeUrl)
Definition: JsonFormat.java:912
com.google.protobuf.util.JsonFormat.PrinterImpl.printValue
void printValue(MessageOrBuilder message)
Definition: JsonFormat.java:883
com.google.protobuf.Message
Definition: Message.java:50
com.google.protobuf::Struct
com.google.protobuf.util.JsonFormat.Printer.appendTo
void appendTo(MessageOrBuilder message, Appendable output)
Definition: JsonFormat.java:320
com.google.protobuf.util.JsonFormat.TypeRegistry.getEmptyTypeRegistry
static TypeRegistry getEmptyTypeRegistry()
Definition: JsonFormat.java:442
com.google.protobuf.util.JsonFormat.Printer.sortingMapKeys
Printer sortingMapKeys()
Definition: JsonFormat.java:302
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition: array.c:111
com.google.protobuf.Descriptors.Descriptor.getFile
FileDescriptor getFile()
Definition: Descriptors.java:681
com.google.protobuf.Descriptors.FieldDescriptor.Type.ENUM
ENUM
Definition: Descriptors.java:1229
com.google.protobuf.util.JsonFormat.ParserImpl.parseFloat
float parseFloat(JsonElement json)
Definition: JsonFormat.java:1747
com.google.protobuf.Descriptors.FieldDescriptor
Definition: Descriptors.java:949
com.google.protobuf.ByteString
Definition: ByteString.java:67
com.google.protobuf.Descriptors.FieldDescriptor.JavaType.MESSAGE
MESSAGE
Definition: Descriptors.java:1271
Value
struct Value Value
Definition: php/ext/google/protobuf/protobuf.h:667


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55