@Override
        public Void structureShape(StructureShape shape) {
            for (MemberShape member : shape.members()) {
                // If the member is required or the type does not require an optional wrapper (such as a list or map)
                // then do not wrap return in an Optional
                writer.pushState(new GetterSection(member));
                if (TraitCodegenUtils.isNullableMember(member)) {
                    writer.openBlock("public $T<$T> get$U() {",
                            "}",
                            Optional.class,
                            symbolProvider.toSymbol(member),
                            symbolProvider.toMemberName(member),
                            () -> writer.write("return $T.ofNullable($L);",
                                    Optional.class,
                                    symbolProvider.toMemberName(member)));
                    writer.popState();
                    writer.newLine();

                    // If the member targets a collection shape and is optional then generate an unwrapped
                    // getter as a convenience method as well.
                    Shape target = model.expectShape(member.getTarget());
                    boolean isListShape = target.isListShape();
                    if (isListShape || target.isMapShape()) {
                        writer.openBlock("public $T get$UOrEmpty() {",
                                "}",
                                symbolProvider.toSymbol(member),
                                symbolProvider.toMemberName(member),
                                () -> writer.write("return $1L == null ? $2T.$3L() : $1L;",
                                        symbolProvider.toMemberName(member),
                                        Collections.class,
                                        isListShape ? "emptyList" : "emptyMap"));
                    }
                } else {
                    writer.openBlock("public $T get$U() {",
                            "}",
                            symbolProvider.toSymbol(member),
                            symbolProvider.toMemberName(member),
                            () -> writer.write("return $L;", symbolProvider.toMemberName(member)));
                    writer.popState();
                }
                writer.newLine();
            }
            return null;
        }
Generates getter methods for each shape member or the value type held by the trait.

<p>Optional member getters will return the member type wrapped in an {@code Optional<T>}.
smithy-trait-codegen/src/main/java/software/amazon/smithy/traitcodegen/generators/GetterGenerator.java