Class TypeEncoder

java.lang.Object
com.google.auto.value.processor.TypeEncoder

final class TypeEncoder extends Object
Encodes types so they can later be decoded to incorporate imports.

The idea is that types that appear in generated source code use encode(javax.lang.model.type.TypeMirror), which will spell out a type like java.util.List<? extends java.lang.Number>, except that wherever a class name appears it is replaced by a special token. So the spelling might actually be `java.util.List`<? extends `java.lang.Number`>. Then once the entire class has been generated, #decode scans for these tokens to determine what classes need to be imported, and replaces the tokens with the correct spelling given the imports. So here, java.util.List would be imported, and the final spelling would be List<? extends Number> (knowing that Number is implicitly imported). The special token `import` marks where the imports should be, and decode(java.lang.String, javax.annotation.processing.ProcessingEnvironment, java.lang.String, javax.lang.model.type.TypeMirror) replaces it with the correct list of imports.

The funky syntax for type annotations on qualified type names requires an adjustment to this scheme. `«java.util.Map` stands for java.util. and `»java.util.Map` stands for Map. If java.util.Map is imported, then `«java.util.Map` will eventually be empty, but if java.util.Map is not imported (perhaps because there is another Map in scope) then `«java.util.Map` will be java.util.. The end result is that the code can contain `«java.util.Map`@`javax.annotation.Nullable` `»java.util.Map`. That might decode to @Nullable Map or to java.util.@Nullable Map or even to java.util.@javax.annotation.Nullable Map.

  • Field Details

  • Constructor Details

    • TypeEncoder

      private TypeEncoder()
  • Method Details

    • encode

      static String encode(TypeMirror type)
      Returns the encoding for the given type, where class names are marked by special tokens. The encoding for int will be int, but the encoding for java.util.List<java.lang.Integer> will be `java.util.List`<`java.lang.Integer`>.
    • encodeRaw

      static String encodeRaw(TypeMirror type)
      Like encode(javax.lang.model.type.TypeMirror), except that only the raw type is encoded. So if the given type is java.util.List<java.lang.Integer> the result will be `java.util.List`.
    • encodeWithAnnotations

      static String encodeWithAnnotations(TypeMirror type)
      Encodes the given type and its type annotations. The class comment for TypeEncoder covers the details of annotation encoding.
    • decode

      static String decode(String text, ProcessingEnvironment processingEnv, String packageName, TypeMirror baseType)
      Decodes the given string, respelling class names appropriately. The text is scanned for tokens like `java.util.Locale` or `«java.util.Locale` to determine which classes are referenced. An appropriate set of imports is computed based on the set of those types. If the special token `import` appears in text then it will be replaced by this set of import statements. Then all of the tokens are replaced by the class names they represent, spelled appropriately given the import statements.
      Parameters:
      text - the text to be decoded.
      packageName - the package of the generated class. Other classes in the same package do not need to be imported.
      baseType - a class or interface that the generated class inherits from. Nested classes in that type do not need to be imported, and if another class has the same name as one of those nested classes then it will need to be qualified.
    • decode

      static String decode(String text, Elements elementUtils, Types typeUtils, String pkg, TypeMirror baseType)
    • className

      private static String className(DeclaredType declaredType)
    • formalTypeParametersString

      static String formalTypeParametersString(TypeElement type)
      Returns the formal type parameters of the given type. If we have @AutoValue abstract class Foo<T extends SomeClass> then this method will return an encoding of <T extends SomeClass> for Foo. Likewise it will return an encoding of the angle-bracket part of:
      Foo<SomeClass>
      Foo<T extends Number>
      Foo<E extends Enum<E>>
      Foo<K, V extends Comparable<? extends K>>.

      The encoding is simply that classes in the "extends" part are marked, so the examples will actually look something like this:
      <`bar.baz.SomeClass`>
      <T extends `java.lang.Number`>
      <E extends `java.lang.Enum`<E>>
      <K, V extends `java.lang.Comparable`<? extends K>>.

    • appendTypeParameterWithBounds

      private static void appendTypeParameterWithBounds(TypeParameterElement typeParameter, StringBuilder sb)
    • appendAnnotations

      private static void appendAnnotations(List<? extends AnnotationMirror> annotationMirrors, StringBuilder sb)